【发布时间】:2014-12-28 23:08:22
【问题描述】:
在以下代码中:
A & getDataA() ;
B & getDataB() ;
void foo()
{
getDataA() = getDataB() ;
}
getDataA() 是否保证在 getDataB() 之前或之后进行评估,或者两个操作数的评估相对于另一个而言是无序的?
注意:我对引用标准的答案感兴趣。
.
P.S.:我的研究到目前为止......
我试图了解标准以找到答案,这是我的研究结果。我的理解是两个操作数的求值是无序的。
但是...(每个引用都来自 C++14 草案 n3797, 5.17 [expr.ass]):
赋值运算符 (=) 和复合赋值运算符都从右到左分组。
这意味着表达式a = b = c ; 真的是a = (b = c) ;。
在所有情况下,赋值顺序在左右操作数的值计算之后,赋值表达式的值计算之前。
第一部分说对于a = b ;,实际分配将在评估a 和b 之后发生。第二部分让我感到困惑:operator +=(或其他复合赋值运算符)我可以理解,但operator = 无法理解。
看着本章的开头(5 表达式 [expr]),我读到:
重载运算符的使用被转换为函数调用,如 13.5 所述。重载的运算符遵循第 5 章规定的语法规则,但操作数类型、值类别和求值顺序的要求被函数调用规则所取代。
这就是让我相信在 A 或 B 不是内置的情况下,两个操作数的计算是未排序的(函数参数的计算是未排序的,除非我遗漏了什么)。
但在上面的例子中,A 和 B 可能是int,所以会调用内置的operator =,而不是函数。
【问题讨论】:
-
这两个函数调用是顺序不确定的:这意味着一个发生在另一个之前,但没有指定哪一个。至于你觉得莫名其妙的部分:规则实际上是说,在
a=(b=c)中,分配给b发生在分配给a之前(实际分配在a和b=c都被评估之后排序; 并且b=c的值是在分配b之后计算的)。 -
@IgorTandetnik : 你能找到使
operator =的操作数评估不确定排序的标准引用吗? -
1.9/15 除非另有说明,否则对单个运算符的操作数和单个表达式的子表达式的求值是无序的...调用函数中的每个求值(包括其他函数调用) ) 在被调用函数的主体执行之前或之后没有特别排序的,相对于被调用函数的执行是不确定的。
-
到目前为止,您的评论在@Loopunroller 之后到达了一点,但更准确。如果你写一个实际的答案,我真的会考虑选择它...... :-)
-
其实答案取决于
A和B的性质。在您的示例中,这些看起来像类,因此=不一定是内置运算符,而是对重载operator=的调用。这将使您引用的部分 5 部分不适用。我想这不是你的本意?