Я опробовал следующий код в VC ++ 2015
#include <iostream>
#include <string>
using namespace std;
int foo(int v)
{
cout << v << endl;
return 10;
}
string bar(int v)
{
cout << v << endl;
return "10";
}
int main()
{
auto a = foo(1) + foo(2) + foo(3);
auto b = bar(10) + bar(20) + bar(30);
cout << "----" << endl << a << endl << b << endl;
return 0;
}
Результат на консоли выглядит следующим образом
1
2
3
30
20
10
----
30
101010
Как мы все знаем, бинарный оператор + имеет ассоциативность слева направо, и это может быть подтверждено 3 вызовами foo
, Они вызываются слева направо по порядку инструкций.
Мой вопрос: почему это не так для string::operator+
? Я попал в некоторые недоразумения?
Вы запутались между ассоциативность а также заказ или оценка.
Порядок оценки аргументов не указан в C ++. Ассоциативность operator +
слева направо, как вы упомянули.
Чтобы понять это, попробуйте подобный фрагмент кода с operator -
От Заказ или оценка (акцент мой)
За исключением случаев, указанных ниже, не существует понятия слева направо или
оценка справа налево в C ++. Это не следует путать с
ассоциативность операторов слева направо и справа налево:
выражение f1 () + f2 () + f3 () анализируется как (f1 () + f2 ()) + f3 () из-за
ассоциативность слева направо оператора +, но вызов функции к f3
может оцениваться первым, последним или между f1 () или f2 () во время выполнения.
Вы предполагаете, что компилятор испускает код для вызова функции непосредственно перед выполнением оператора сложения. Это не обязательно правда. Фактическая последовательность операций может быть просто:
Конечно, поскольку сложение симметрично, порядок сложения на самом деле не имеет значения.
C ++ не требует, в этом случае, вызов функции должен происходить немедленно вместе с дополнением. Правила, регулирующие порядок оценки, на самом деле довольно сложны. Достаточно сказать, что в этом случае порядок вызовов функций не указан, и каждая реализация C ++ может выполнять вызовы функций в любом относительном порядке. Фактически, относительный порядок может отличаться при каждом запуске программы (конечно, маловероятно, но это все равно будет соответствовать требованиям).