为什么在c++ 11大括号初始化项中可以使用operator=而不能使用operator== ?
Why can I use operator= but not operator== with C++11 brace-initializers?
请看下面的例子:
struct Foo
{
int a;
int b;
bool operator == (const Foo & x)
{
return a == x.a && b == x.b;
}
};
int main ()
{
Foo a;
a = {1, 2};
if (a == {1, 2}) // error: expected primary-expression before ‘{’ token
{
}
}
line a={1,2}
is fine。大括号被转换为Foo
以匹配隐式operator=
方法的参数类型。如果operator=
是用户定义的,它仍然工作。
if (a=={1,2}})
行出现错误。
为什么表达式{1,2}
不转换为Foo
来匹配用户自定义的operator==
方法?
列表初始化不能作为一般情况下操作符的实参。c++ 11标准第8.5.4/1段:
[…可以使用List-initialization
——作为变量定义的初始化式(8.5)
-作为new表达式的初始化式(5.3.4)
-在return语句(6.6.3)
-作为for-range初始化式(6.5)
- 作为函数参数 (5.2.2)
-作为下标(5.2.1)
—作为构造函数调用的参数(8.5,5.2.3)
—作为非静态数据成员的初始化式(9.2)
-在mems初始化式中(12.6.2)
-赋值操作右侧的 (5.17)
最后一项解释了为什么允许在operator =
的右侧进行列表初始化,尽管通常不允许对任意操作符进行列表初始化。
但是,由于上面的第五项,它可以用作常规函数调用的参数,如下所示:
if (a.operator == ({1, 2}))
不支持。
初始化列表被显式定义为在初始化 ([C++11: 8.5.4]
)和赋值:
的右侧
[C++11: 5.17/9]:
A 带括号的初始化列表可能出现在
- 对标量的赋值,在这种情况下,初始化列表最多只能包含一个元素。
x={v}
(其中T
是表达式x
的标量类型)的含义与x=T(v)
相同,只是不允许进行窄化转换(8.5.4)。x={}
的含义为x=T()
- 由用户定义的赋值操作符定义的赋值,在这种情况下,初始化列表作为参数传递给操作符函数。
没有标准的措辞允许其他任意的情况。
如果允许,在本例中,{1,2}
的类型将相当模糊。这将是一个复杂的语言特性来实现
需要显式强制转换。
if (a == (Foo){1, 2})
{
}
使用包含用户定义类型a和==操作符的表达式时重载操作符函数被调用,根据你给出的定义,它需要一个类Foo
对象引用的参数。所以表达式应该是a==b
其中b是类Foo
的对象通过这个表达式,你可以比较b和a的数据成员,从而知道它们是否相等
没有真正的原因。
c++是一个委员会努力的结果,所以有时奇怪但经过深思熟虑的决定可能会因为复杂的政治/社会动态而被忽略。
c++语法很难。很努力。几乎难以置信的困难。甚至有这样的规则:"如果你可以将这个任意长的令牌序列解析为this或that,那么它就是this"。
编译器甚至花了很多年才简单地就什么是c++、什么不是c++达成一致。
在这种情况下,我大胆的猜测是他们不喜欢看起来非常相似的情况:
MyClass x = {...};
MyClass y; y = {...};
将以不同的方式处理,因此有一个特殊的赋值条款来允许语法。
从技术角度来看,我看不出允许其他操作符也使用赋值有什么问题,另一方面,如果存在问题(例如重载,模板实例化等),我不知道赋值如何能够逃脱它们。
<标题>编辑g++不仅允许使用严格的operator=
,还允许使用operator+=
、operator-=
和类似的"增广赋值"。可能只有在允许非成员重载(赋值和增广赋值操作符禁止)时才会出现逻辑问题。
- 是否可以使C++类成为Objc类的委托
- 是否可以使一个类成为两个不同层次结构的子类?
- 是否有编译器标志可以使较新的 gcc 版本像旧版本一样构建
- C 可以使destuructor不称为班级成员和基类攻击方的灾难
- 可以使未命名的结构静态
- 是否可以使整数仅收到一个单个数字而不是两个接收输入
- C++:有哪些常规方法可以使代码更有效地用于大数字
- 是否可以使 std 容器使用默认运算符为新?
- LD_BIND_NOW可以使可执行文件运行得更慢?
- 是否可以使头文件使文本居中?- 在控制台中
- 有什么方法可以使核心忙碌等待
- 有没有一种技术可以使虚函数在所有派生类中强制重写?
- 有没有一种方法可以使全局函数/静态成员函数一次可呼出
- 是否有一种方法可以使此C 14递归模板在C 17中短
- 编写一个可以使二维数组平坦的函数
- 有哪些优化技巧可以使我的代码运行得更快
- 有没有更好的方法可以使此代码线程安全?线程局部静态似乎是一个生硬的工具
- 如果必须在同一向量上写入线程,是否可以使用线程
- 对于具有两个模板化变量的模板化类,是否可以使一个 var 引用另一个 var
- C 中的内容可以使Windows 8应用程序不在手臂上运行