[英]For { A=a; B=b; }, will “A=a” be strictly executed before “B=b”?
[英]Equivalence of “a @= b” and “a = a @ b”
它经常被提出(实际上我认为即使标准也暗示它), a @= b
和a = a @ b
是等价的。 在这里,我使用@
代替一系列符号,例如&
和^
。
但是我怀疑它们在运行时是等效的,特别是如果a
是原子类型 。 例如:
std::atomic_int a;
a ^= 1;
(这是一种切换a
的原子方式)被认为等同于
a = a ^ 1;
但是,由于分配,第二种方式不是原子的。
因此,我怀疑他们的字面等价和编译器(无论标准说什么) 无法将较短的形式更改为较长的形式。
我对么?
语言标准仅定义内置运算符的行为,而不是“用户定义的”重载。 从语言的角度来看, std::atomic_int
没有内置的运算符(正式的是“用户定义的类型”); std::atomic_int
是std::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.