use*_*358 5 c++ initializer-list overload-resolution compiler-bug visual-studio-2013
你能解释一下STL容器如何使用空的初始化列表处理赋值运算符?
当我做这样的事情:
vector<int> v;
v = { };
Run Code Online (Sandbox Code Playgroud)
被调用的函数不是:
vector& operator= (initializer_list<value_type> il);
Run Code Online (Sandbox Code Playgroud)
但:
vector& operator= (vector&& x);
Run Code Online (Sandbox Code Playgroud)
另一方面,当我和我自己的班级做类似的事情时:
struct A {
A& operator= (const A&) { return *this; }
A& operator= (A&&) { return *this; }
A& operator= (initializer_list<int>) { return *this; }
};
/* ... */
A a;
a = { };
Run Code Online (Sandbox Code Playgroud)
代码不能在VS2013上编译,并说:
error C2593: 'operator =' is ambiguous
Run Code Online (Sandbox Code Playgroud)
如果列表不为空,它工作正常,它只是用初始化列表调用函数.只有当列表为空时才会出现问题,在向量上调用rvalue赋值运算符,在我的类上它会给出错误.
如何在向量和其他容器中处理这种情况?
这似乎是一个 bug clang( see it live ) 和 gcc( see it live ) 接受这个程序并选择看起来正确的std::initializer_list重载,因为这是完全匹配的,这在C++ 草案标准部分中有所介绍示例中的13.3.3.1.5 列表初始化序列第2段:
void f(std::initializer_list<int>);\nf( {1,2,3} ); // OK: f(initializer_list<int>) identity conversion\nf( {\xe2\x80\x99a\xe2\x80\x99,\xe2\x80\x99b\xe2\x80\x99} ); // OK: f(initializer_list<int>) integral promotion\nf( {1.0} ); // error: narrowing\nRun Code Online (Sandbox Code Playgroud)\n\n我们有一个完全匹配的身份转换。
\n\n对于参考重载,我们转到第5段,它说(重点是我的未来):
\n\n\n\n\n否则,如果参数是引用,请参见 13.3.3.1.4。[注:本节中的规则将适用于初始化底层临时以供参考。\xe2\x80\x94结束注]
\n
表示创建了临时文件,然后我们可以将规则应用于生成的临时文件。这将是用户定义的转换,比完全匹配更糟糕。
\n\n所以这不应该是含糊的。
\n\n更新
\n\n看起来有两个与此相关的活跃错误:
\n\n| 归档时间: |
|
| 查看次数: |
360 次 |
| 最近记录: |