简体   繁体   English

C ++中std :: unordered_map的演绎指南17

[英]Deduction guides for std::unordered_map in C++17

I have read about deduction guides for std::unordered_map in C++17 from using a cppreference . 我已经阅读了有关使用cppreference的 C ++ 17中std::unordered_map演绎指南。

Then tried to run following example, which is copied from cppreference. 然后尝试运行以下示例,该示例是从cppreference复制的。

#include <unordered_map>
int main() {
// std::unordered_map m1 = {{"foo", 1}, {"bar", 2}}; // Error: braced-init-list has no type
                                                     // cannot deduce pair<const Key, T> from
                                                     // {"foo", 1} or {"bar", 2}
   std::unordered_map m1 = std::initializer_list<
                        std::pair<char const* const, int>>({{"foo", 2}, {"bar", 3}}); // guide #2
   std::unordered_map m2(m1.begin(), m1.end()); // guide #1
}

But, the compiler gives an error. 但是,编译器会出错。

main.cpp: In function 'int main()':
main.cpp:7:84: error: class template argument deduction failed:
                         std::pair<char const* const, int>>({{"foo", 2}, {"bar", 3}}); // guide #2
                                                                                    ^
main.cpp:7:84: error: no matching function for call to 'unordered_map(std::initializer_list<std::pair<const char* const, int> >)'
In file included from /usr/local/include/c++/7.2.0/unordered_map:48:0,
                 from main.cpp:1:
/usr/local/include/c++/7.2.0/bits/unordered_map.h:101:11: note: candidate: template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> unordered_map(std::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>)-> std::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>
     class unordered_map
           ^~~~~~~~~~~~~

Why does compiler give an error? 为什么编译器会出错?

edit: I am updating this answer after discussing the issue with a developer of the GCC C++ library (libstdc++). 编辑:我在与GCC C ++库(libstdc ++)的开发人员讨论问题后更新了这个答案。 The edited answer has more details, rational, and a future direction. 编辑后的答案有更多细节,理性和未来方向。

Technically this is a compiler bug in GCC, while clang sticks to the standard. 从技术上讲,这是GCC中的编译器错误,而clang坚持标准。 The first guide in your code works with clang-6 -stdlib=libc++. 代码中的第一个指南适用于clang-6 -stdlib = libc ++。

std::unordered_map m1 = std::initializer_list<
                        std::pair<char const* const, int>>({{"foo", 2}, {"bar", 3}}); // guide #2

So does 那样做

std::unordered_map m2{
std::pair<char const* const, int>{"foo", 2}, {"bar", 3}}; // guide #2

But GCC deviates from the standard and allows: 但海湾合作委员会偏离标准并允许:

std::unordered_map m2{std::pair{"foo", 2}, {"bar", 3}};

Which is effectively the same as 这实际上是一样的

// not const char*const, but rather const char*
std::unordered_map m2{std::pair<const char*, int>{"foo", 2}, {"bar", 3}};

This is not standard conforming, since the key part of the pair is supposed to be const. 这不符合标准,因为该对的关键部分应该是const。 This is in fact better than the standard, because this deviation makes it possible to deduce the template parameters. 这实际上比标准更好,因为这种偏差使得可以推导出模板参数。 This is in contrast to the standard guides makes it impossible to deduce std::unordered_map template parameters, without writing them explicitly, which is quite useless. 这与标准指南形成对比,因此无法推断std::unordered_map模板参数,而无需明确地编写它们,这是无用的。

This issue is mentioned on the Library Working Group (LWG) page at Issue 3025: Map-like container deduction guides should use pair<Key, T>, not pair<const Key, T> . 问题3025的图书馆工作组(LWG)页面上提到了这个问题:类似地图的容器扣除指南应该使用对<Key,T>,而不是对<const Key,T> GCC simply decided to go with a nonconforming deduction guides, which make this feature useful, rather than sticking with usefulness standard-conforming guides. GCC只是决定使用不合格的演绎指南,这使得这个功能很有用,而不是坚持使用符合标准的指南。

Most likely, this issue will have an official DR soon, making GCC's implementation conform to the amended standard. 最有可能的是,这个问题很快就会有正式的DR,这使得GCC的实施符合修订后的标准。

NOTE: You can read the details in the GCC bug report on this issue, for more details. 注意:您可以阅读有关此问题的GCC错误报告中的详细信息,以获取更多详细信息。

PS I hope you know what you are doing, making a key of type const char* . PS我希望你知道你在做什么,制作一个const char*类型的键。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM