我有一个std::map我正在尝试初始化初始化列表.我在两个地方以两种不同的方式做到这一点.第一个工作,而另一个工作导致标题中提到的错误.
这是有效的:
void foo() {
static std::map<std::string, std::string> fooMap =
{
{ "First", "ABC" },
{ "Second", "DEF" }
};
}
Run Code Online (Sandbox Code Playgroud)
虽然这个没有:
class Bar {
public:
Bar();
private:
std::map<std::string, std::string> barMap;
};
Bar::Bar() {
barMap = { // <-- this is the error line
{ "First", "ABC" },
{ "Second", "DEF" }
};
}
Run Code Online (Sandbox Code Playgroud)
为什么在尝试初始化类成员时会出现错误,而静态映射有效?目前,我可以通过首先创建一个局部变量然后将其与成员交换来填充成员,如下所示:
Bar::Bar() {
std::map<std::string, std::string> tmpMap = {
{ "First", "ABC" },
{ "Second", "DEF" }
};
barMap.swap(tmpMap);
}
Run Code Online (Sandbox Code Playgroud)
然而,与直接填充成员相比,这感觉相当反直觉.
编辑:这是编译器输出.
Col*_*mbo 12
这是编译器重载解析机制中的错误 - 或其标准库实现.过载分辨率明确指出[over.ics.rank]/3
- 列表初始化序列
L1是比列表初始化序列更好的转换序列,L2如果L1转换std::initializer_list<X>为某些X而L2不是.
在这里,X是std::pair<std::string, std::string>.L1将列表转换为参数
map& operator=( std::initializer_list<value_type> ilist );
Run Code Online (Sandbox Code Playgroud)
同时L2将列表转换为以下函数的参数之一:
map& operator=( map&& other );
map& operator=( const map& other );
Run Code Online (Sandbox Code Playgroud)
这显然不是initializer_lists.
barMap = decltype(barMap){
{ "First", "ABC" },
{ "Second", "DEF" }
};
Run Code Online (Sandbox Code Playgroud)
哪个应该选择移动赋值运算符(使用VC++演示).临时也应该根据复制省略进行优化.