繁体   English   中英

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

[英]Equivalence of “a @= b” and “a = a @ b”

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

但是我怀疑它们在运行时是等效的,特别是如果a原子类型 例如:

std::atomic_int a;
a ^= 1;

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

a = a ^ 1;

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

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

我对么?

语言标准仅定义内置运算符的行为,而不是“用户定义的”重载。 从语言的角度来看, std::atomic_int没有内置的运算符(正式的是“用户定义的类型”); std::atomic_intstd::atomic<int>的typedef,它定义了一些operator@= overload,但没有简单的@ 因此对于

std::atomic_int i;
i ^= 1;

第二行变为:

i.operator^=( 1 );

但对于:

std::atomic_int i;
i = i ^ 1;

第二行变为:

i.operator=( i.operator int() ^ 1 );

有人可能会争辩说,这是“左手参数被评估两次,而不是一次”所暗示的内容的一部分。 然而,更一般地说,重载运算符的定义是运算符所需的任何内容: operator+= can(就语言而言)实际上是减去的,即使添加了operator+ (我有几种情况,其中operator+实际上是operator+= 。这通常不是一个好主意,在我的情况下,它只发生在专门设计用于std::accumulate ,并记录为仅用于那种情况。)标准根本不限制用户定义的运算符

你是对的。 实际上,它们甚至不能保证在一般的非原子情况下是等价的,因为类可以为+=+提供完全独立的不同重载。

内置的运营商有一个等价,除了a @= b只计算a一次,而a = a @ b计算它的两倍。

但是,这些不是内置运算符,而是标准库提供的重载。 它们被视为独立的,不相关的函数,因此编译器不能将其中一个更改为另一个。 (事实上​​,正如注释中所指出的,只有赋值运算符被重载为原子类型 - 你必须显式加载和存储值才能使用非原子形式)。

您可以定义^=^来完成不同的事情。 因此,没有编译器只能在需要时不能将一个更改为另一个

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM