考虑以下代码片段:
#include <unordered_map>
void foo(const std::unordered_map<int,int> &) {}
int main()
{
foo({});
}
使用GCC 4.9.2会失败,并显示以下错误信息:
map2.cpp:7:19: error: converting to ‘const std::unordered_map<int, int>’ from initializer list would use explicit constructor ‘std::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map(std::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::size_type, const hasher&, const key_equal&, const allocator_type&) [with _Key = int; _Tp = int; _Hash = std::hash<int>; _Pred = std::equal_to<int>; _Alloc = std::allocator<std::pair<const int, int> >; std::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::size_type = long unsigned int; std::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::hasher = std::hash<int>; std::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::key_equal = std::equal_to<int>; std::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::allocator_type = std::allocator<std::pair<const int, int> >]’
与其他编译器/库实现的测试:
- GCC < 4.9接受此代码而不抱怨,
- 带有libstdc++的Clang 3.5会失败并显示类似的消息,
- 带有libc++的Clang 3.5将接受此代码,
- ICC 15.something 接受此代码(不确定它使用的是哪个标准库)。
还有几个令人困惑的点:
- 用
std::map
替换std::unordered_map
会使错误消失, - 用
foo({{}})
代替foo({})
也会使错误消失。
同样,在所有情况下,将{}
替换为非空初始化列表都能按预期工作。
所以我的主要问题是:
- 谁在这里正确?上面的代码格式良好吗?
- 双大括号语法
foo({{}})
到底是如何使错误消失的?
编辑修正了一些拼写错误。