5

你能解释一下 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

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

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

4

1 回答 1

3

这似乎是一个错误clang(现场观看)和gcc(现场观看)接受这个程序并选择看起来正确的std::initializer_list重载,因为这是完全匹配的,这在C++草案标准部分部分有所介绍示例中的13.3.3.1.5 列表初始化序列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。[注意:本节中的规则将适用于初始化底层临时以供参考。——尾注]

表示创建了临时的,然后我们可以将规则应用于生成的临时。这将是一个用户定义的转换,它比精确匹配更糟糕。

所以这不应该是模棱两可的。

更新

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

于 2014-01-17T04:02:00.397 回答