多重赋值(a = b) = c语法是如何工作的?
How does multiple assignment (a = b) = c syntax work?
如果a
, b
和c
是int
s或任何其他基本类型,那么像(a = b) = c;
这样的语句如何在c++中工作?
赋值表达式a = b
在C中不是左值,但在c++中是:
-
C11, 6.5.14(赋值操作符):
赋值操作符将值存储在左操作数指定的对象中。赋值表达式具有赋值后左操作数的值,但不是左值。
-
c++ 14, 5.18 [expr。(赋值和复合赋值操作符):
赋值操作符(
=
)和复合赋值操作符都是由右向左组合的。它们都需要一个可修改的左值作为左操作数,并返回一个指向左操作数的左值。
在c++从C进化而来的过程中,有几个表达式被赋予了"左值感知"功能,因为左值在c++中比在C中重要得多。在C中,一切都是微不足道的(用c++的话说,都是微不足道的可复制和微不足道的可破坏),所以左值到右值的转换(或C所说的"左值转换")并不痛苦。在c++中,复制和析构是非常重要的概念,通过使表达式保持左值性,可以避免大量一开始就不需要的复制和析构。
另一个例子是条件表达式(a ? b : c
),它在C中不是左值,但在c++中可以是左值。
这种语言演变的另一个有趣的产物是C有四个定义良好的存储持续时间(自动、静态、线程局部和动态),但在c++中这变得更加混乱,因为临时对象在c++中是一个重要的概念,几乎需要自己的存储持续时间。(例如Clang内部有第五个"完整表达式"存储持续时间。)临时值当然是左值到右值转换的结果,因此通过避免转换,可以少担心一件事。
(请注意,所有这些讨论只适用于各自的核心语言表达式。c++还具有操作符重载的独立的、不相关的特性,该特性生成函数调用表达式,该表达式具有函数调用的所有常用语义,除了语法之外与操作符无关。例如,您可以定义一个重载的operator=
,它返回一个右值或void
(如果您愿意的话)
在c++中,对于内置类型,a = b
的结果是对a
的引用;您可以为该引用赋值,就像对任何其他引用一样。因此,(a = b) = c
将b
的值赋给a
,然后将c
的值赋给a
。
对于用户定义类型,这可能不适用,尽管通常的习惯用法是赋值操作符返回对左参数的引用,因此用户定义类型的行为模仿内置类型的行为:
struct S {
S& operator=(const S& rhs) {
return *this;
}
};
现在,S a, b, c; (a = b) = c;
意味着调用a.operator=(b)
,返回对a
的引用;然后调用S::operator=
的结果和c
,有效地调用a.operator=(c)
。
(a = b) = c
在c++中是有效的语句。这里'='作为赋值操作符。这里,b的值将被赋给a, c的值将被赋给a,从右向左优先。
int a = 5;
int b = 2;
int c = 7;
int answer = (a = b) = c;
cout << answer << endl;
输出:7
以下是一些猜测,如果我错了,请纠正我。
当他们发明操作符重载时,他们必须为任何类T
提供一个标准的赋值操作符的一般形式。例如:
T& T::operator=(T);
T& T::operator=(const T&);
在这里,它返回一个对T
的引用,而不仅仅是T
,以使x = (y = z)
这样的三部分赋值高效,而不需要副本。
它可以返回const
对T
的引用,这将使不需要的赋值(a = b) = c
出错。我猜想他们没有使用这个有两个原因:
- 更短的代码-不需要一直写所有这些
const
(const
的细节-正确性当时还不清楚) - 更灵活-允许像
(a = b).print()
这样的代码,其中print
是一个非const
方法(因为程序员懒惰/忽视const
的正确性)
基本类型(不是class
类型)的语义被推断为:
int& operator=(int&, int); // not real code; just a concept
"返回类型"不是const int&
,所以它匹配class
es的模式。因此,如果有缺陷的(a = b) = c
代码对用户定义类型有效,那么它也应该对内置类型有效,这是c++设计原则所要求的。一旦你记录了这些东西,你就不能改变它了,因为向后兼容性。
- QSqlquery prepare()和bindvalue()不工作
- 导入库可以跨dll版本工作吗
- 以螺旋方式打印矩阵的程序.(工作不好)
- 对象指针在c++中是如何工作的
- 为什么在Windows上的VS 2019和Clang 9中"size_t"在没有标题的情况下工作
- VSOMEIP-2个设备之间的通信(TCP/UDP)不工作
- 为字符串中每 N 个字符插入空格的函数没有按照我认为的方式工作?
- C++为线程工作动态地分割例程
- 为什么我的 std::ref 无法按预期工作?
- 布尔比较运算符是如何在C++中工作的
- SampleConsensusPrerejective(ext.RANSAC)是如何真正工作的
- 不确定要在我的main中放入什么才能使我的代码正常工作
- 为什么std::condition_variable notify_all的工作速度比notify_one快(对于随机请
- <<操作员在下面的行中工作
- 有人能解释一下为什么下界是这样工作的吗C++的
- ExtractIconEx:可以工作,但偶尔会崩溃
- C++中的memset函数工作不正常
- 当我在第一个循环中使用"auto"时,它工作正常,但是使用"int"它会给出错误,为什么?
- 链表c++插入,所有情况都已检查,但没有任何工作
- 当 int 方法工作正常时,void 方法有何不同,或者为什么我不能调用 void 方法?