它经常被提出(实际上我认为即使是标准也提到了它),a @= b
和a = a @ b
是等价的。在这里,我使用@
代替&
和^
等一系列符号。
但我怀疑它们在运行时是否相同,特别是如果a
是原子类型。例如:
std::atomic_int a;
a ^= 1;
(这是切换a
的原子方式)被认为等同于
a = a ^ 1;
但是,由于分配,第二种方式是而不是原子。
因此,我怀疑他们的字面等价和编译器(不论标准是什么)不能够将较短的形式更改为较长的形式。
我说错了吗?
答案 0 :(得分:18)
语言标准仅定义内置的行为
运营商,而不是"用户定义"重载。来自
从语言的角度来看,没有内置的运算符
std::atomic_int
(正式为"用户定义类型");
std::atomic_int
是std::atomic<int>
的typedef,其中包含operator@=
定义了一些@
重载,但没有简单的std::atomic_int i;
i ^= 1;
。
i.operator^=( 1 );
第二行变为:
std::atomic_int i;
i = i ^ 1;
但是:
i.operator=( i.operator int() ^ 1 );
第二行变为:
operator+=
有人可能会说,这是&#34; the暗示的一部分
左手参数被评估两次,而不是一次&#34;。
然而,更一般地说,重载的定义
运营商是运营商想要的任何人:
operator+
可以(就语言而言)
实际上是减去,即使添加了operator+
。 (我是一对夫妇
operator+=
实际上std::accumulate
的情况。这是
不通常是一个好主意,而在我的情况下,它只会发生
专为与{{1}}一起使用而设计的课程
记录仅用于该情况。)标准简单
不限制用户定义的运算符
答案 1 :(得分:10)
你是对的。实际上,它们甚至不能保证在一般的非原子情况下是等价的,因为一个类可以为完全独立的+=
和+
提供不同的重载。
答案 2 :(得分:3)
内置运算符具有等效性,但a @= b
仅评估a
一次,而a = a @ b
评估两次。
但是,这些不是内置运算符,而是标准库提供的重载。它们被视为独立的,不相关的函数,因此编译器不能将其中一个更改为另一个。 (事实上,正如注释中所指出的,只有赋值运算符因原子类型而重载 - 您必须显式加载和存储该值才能使用非原子形式。)
答案 3 :(得分:2)
您可以定义^=
和^
来完成不同的事情。因此,没有编译器只有在想要