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

时间:2019-03-27 21:54:06

标签: c++ c++17 assignment-operator

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

  1. right()
  2. left()

按此顺序。 here.

已将right()放在第一位

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

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

2 个答案:

答案 0 :(得分:24)

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

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

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

答案 1 :(得分:16)

除了执行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
}

如果我们使用相同的地图,但是这样做:

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

如果Right()抛出:

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