空initializer_list上的赋值运算符

时间:2014-01-14 18:07:53

标签: c++ visual-studio-2013 initializer-list overload-resolution compiler-bug

你能解释一下STL容器如何使用空的初始化列表处理赋值运算符吗?

当我做这样的事情时:

vector<int> v;
v = { };

被调用的函数是

vector& operator= (initializer_list<value_type> il);

但:

vector& operator= (vector&& x);
另一方面,当我和我自己的班级做类似的事情时,

struct A {
    A& operator= (const A&) { return *this; }
    A& operator= (A&&) { return *this; }
    A& operator= (initializer_list<int>) { return *this; }
};

/* ... */

A a;
a = { };

代码无法在VS2013上编译,并说:

error C2593: 'operator =' is ambiguous

如果列表不为空,它工作正常,它只是用初始化列表调用函数。问题仅在列表为空时出现,在向量上调用rvalue赋值运算符,在我的类上它给出错误。

如何在向量和其他容器中处理这种情况?

1 个答案:

答案 0 :(得分:3)

这似乎是一个bug clang( see it live )和gcc( see it live )接受此程序并选择 std :: initializer_list 重载看起来是正确的,因为这是完全匹配C++ draft standard部分13.3.3.1.5 列表初始化序列<来自示例的/ em>段 2

void f(std::initializer_list<int>);
f( {1,2,3} ); // OK: f(initializer_list<int>) identity conversion
f( {’a’,’b’} ); // OK: f(initializer_list<int>) integral promotion
f( {1.0} ); // error: narrowing

我们有身份转换,这是完全匹配

对于参考重载,我们转到段落 5 它说(强调我的前进):

  

否则,如果参数是参考,请参见13.3.3.1.4。 [注意:本节中的规则适用于初始化参考的基础临时。 - 后注]

表示临时创建,然后我们可以将规则应用于结果临时。这将是用户定义的转化,它比完全匹配更糟糕。

所以这不应该含糊不清。

更新

看起来有两个与此相关的活动错误: