"a @= b"和"a = a @ b"的等效性

Equivalence of "a @= b" and "a = a @ b"

本文关键字:      更新时间:2023-10-16

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@=重载,但没有定义简单的@。所以对于

std::atomic_int i;
i ^= 1;

第二行变为:

i.operator^=( 1 );

但适用于:

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

第二行变为:

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

有人可能会说,这是"左手论点被评估两次,而不是一次"。然而,更普遍的是,重载的定义运算符是运算符作者想要的:operator+=可以(就语言而言)实际上是相减,即使operator+相加。(我有几个CCD_ 15实际执行CCD_。这是不是通常是个好主意,在我的情况下,它只发生在专门设计用于std::accumulate的类,以及仅在这种情况下使用。)标准很简单不限制用户定义的运算符

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

内置运算符具有这种等价性,只是a @= b只对a求值一次,而a = a @ b对其求值两次。

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

您可以定义^=^来做完全不同的事情。因此,任何编译器都不能仅在想要

时将一个更改为另一个
相关文章:
  • 没有找到相关文章