空的inizalizer_list上的赋值运算符

assignment operator on empty inizializer_list

本文关键字:赋值运算符 list inizalizer 空的      更新时间:2023-10-16

您能解释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

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

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

这似乎是一个bug 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。[注意:本节中的规则将适用于初始化引用的基础临时。--结束注释]

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

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

更新

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

  • 编译器对是否使用initializer_list赋值运算符感到困惑
  • VC++12 RC无法在initializer_list启用的赋值运算符和std::pair列表元素的规范运算符之间进行选择