"a @= b"和"a = a @ 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@=
重载,但没有定义简单的@
。所以对于
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
对其求值两次。
然而,这些不是内置运算符,而是标准库提供的重载。它们被视为独立的、不相关的函数,因此编译器不能将其中一个函数更改为另一个函数。(事实上,正如注释中所指出的,只有赋值运算符被重载用于原子类型——您必须显式地加载和存储值才能使用非原子形式)。
您可以定义^=
和^
来做完全不同的事情。因此,任何编译器都不能仅在想要
- 没有找到相关文章