В выражении left () = right () почему сначала выполняется последовательность right ()? - PullRequest
11 голосов
/ 28 марта 2019

В C ++ выражение left() = right() оценивает

  1. right()
  2. left()

в этой последовательности.right() идет первым, как уже обсуждалось .

Я не могу придумать причину, по которой right() должен идти первым.Ты можешь?Я предполагаю, что существует причина.В противном случае стандарт вряд ли скажет, что он говорит, но учтите: right() вернет некоторый результат.На уровне машинного кода ЦПУ не нужно знать, куда поместить результат right() вернется, прежде чем просить right() вернуть его?

Если вам случится узнать, о чем думал стандартный комитет(потому что вы были в комнате или читали записку), это здорово: я хотел бы прочитать ваш ответ.Однако мой актуальный вопрос более скромный.Все, что я хочу знать - существует ли правдоподобная причина и какова может быть эта причина.

Ответы [ 2 ]

24 голосов
/ 28 марта 2019

В предложении P0145 , которое ввело этот порядок оценки, авторы привели следующий пример:

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

В этой ситуации оценка слева направо даст 1, тогда какоценка справа налево дала бы 0. Наличие результата равным 0, благодаря оценке справа налево, более близко соответствует нашей интуиции, что значение, которое должно быть назначено, - это значение, существовавшее непосредственно перед вычислением выражения присваивания..

17 голосов
/ 28 марта 2019

В дополнение к не интуитивному результату при выполнении того, что показал Брайан:

#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] не будет создан вообще.

...