我已经阅读了使用cppreference来了解C ++ 17中std::unordered_map
的演绎指南。
然后尝试运行以下示例,该示例是从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
}
但是,编译器会出错。
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
^~~~~~~~~~~~~
为什么编译器会出错?
答案 0 :(得分:2)
edit:与GCC C ++库(libstdc ++)的开发人员讨论了问题之后,我正在更新此答案。修改后的答案具有更多细节,合理性和未来发展方向。
从技术上讲,这是GCC中的编译器错误,而clang则遵循标准。您的代码中的第一本指南适用于clang-6 -stdlib = libc ++。
std::unordered_map m1 = std::initializer_list<
std::pair<char const* const, int>>({{"foo", 2}, {"bar", 3}}); // guide #2
也是
std::unordered_map m2{
std::pair<char const* const, int>{"foo", 2}, {"bar", 3}}; // guide #2
但GCC偏离标准并允许:
std::unordered_map m2{std::pair{"foo", 2}, {"bar", 3}};
实际上与
相同// not const char*const, but rather const char*
std::unordered_map m2{std::pair<const char*, int>{"foo", 2}, {"bar", 3}};
这不符合标准,因为该对的关键部分应该是const。实际上,这比标准更好,因为这种偏差使得可以推导出模板参数。这与标准指南相反,标准指南使我们无法推断std::unordered_map
模板参数,而无需显式地编写它们,这是毫无用处的。
此问题在Issue 3025: Map-like container deduction guides should use pair<Key, T>, not pair<const Key, T>的图书馆工作组(LWG)页面上提到。 GCC只是决定使用不符合标准的推论指南,该指南使此功能有用,而不是坚持遵循符合标准的有用性指南。
此问题很可能很快就会有正式的DR,使GCC的实施符合修订后的标准。
注意:您可以在GCC bug report中阅读有关此问题的详细信息,以了解更多信息。
P.S。希望您知道自己在做什么,键入const char*
类型的密钥。