在表达式left()= right()中,为什么right()首先被排序?

thb*_*thb 12 c++ assignment-operator c++17

在C ++中,表达式left() = right()求值

  1. right()
  2. left()

按此顺序。该right()先行,如已经讨论这里。

我想不出right()先走的理由。你是否可以?我认为这是有原因的。否则,该标准几乎不会说出它的意思,而是要考虑:right()将返回一些结果。在机器代码级别上,CPU是否不需要在将结果right()返回之前就知道将结果放回何处right()

如果您碰巧知道标准委员会在想什么(因为您在房间里或已经阅读备忘录),那就太好了:我想阅读您的答案。但是,我的实际问题较为温和。我只想知道是否存在合理的原因,以及该原因可能是什么。

Bri*_*ian 24

在介绍此评估顺序的提案P0145中,作者给出了以下示例:

#include <map>
int main() {
    std::map<int, int> m;
    m[0] = m.size();
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,从左到右的评估将得到1,而从右到左的评估将得到0。由于从右到左的评估,结果为0,这更符合我们的直觉,即应该被赋值的是在赋值表达式被求值之前就已经存在的那个。


Ted*_*gmo 18

除了执行Brian所示的直观结果之外:

#include <map>
int main() {
    std::map<int, int> m;
    m[0] = m.size(); // before C++17 m[0] could be 0 or 1 - it was implementation defined
}
Run Code Online (Sandbox Code Playgroud)

如果我们使用相同的地图,但执行以下操作:

#include <map>
int main() {
    std::map<int, int> m;
    m[0] = Right(); // Right() may throw
}
Run Code Online (Sandbox Code Playgroud)

如果Right()抛出:

在C ++ 17之前,您可能会在m[0](从左到右)中获得默认的构造元素,或者m[0]根本不会创建(从右到左)。在C ++ 17中m[0]根本不会创建。