“a = b”和“a = a @ b”的等价性

时间:2014-04-25 08:58:37

标签: c++

它经常被提出(实际上我认为即使是标准也提到了它),a @= ba = a @ b是等价的。在这里,我使用@代替&^等一系列符号。

但我怀疑它们在运行时是否相同,特别是如果a原子类型。例如:

std::atomic_int a;
a ^= 1;

(这是切换a的原子方式)被认为等同于

a = a ^ 1;

但是,由于分配,第二种方式是而不是原子。

因此,我怀疑他们的字面等价和编译器(不论标准是什么)能够将较短的形式更改为较长的形式。

我说错了吗?

4 个答案:

答案 0 :(得分:18)

语言标准仅定义内置的行为 运营商,而不是&#34;用户定义&#34;重载。来自 从语言的角度来看,没有内置的运算符 std::atomic_int(正式为&#34;用户定义类型&#34;); std::atomic_intstd::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)

您可以定义^=^来完成不同的事情。因此,没有编译器只有在想要

时才能将其更改为另一个