Ответ 1
Полное выражение
foo1() = foo2() = foo3() = 7
может быть абстрагировано с помощью следующего дерева:
=
/ \
foo1() =
/ \
foo2() =
/ \
foo3() 7
Листья этого дерева могут быть оценены в любом порядке. Ваш компилятор свободен в выборе. Только для вызова оператора присваивания сначала должны быть оценены выражения, зависающие на них. В вашем случае листья оцениваются в порядке foo1()
, foo2()
, а затем foo3()
.
Правовая ассоциативность =
видна только в форме дерева, но не в порядке оценки. Дерево для
std::cout << foo1() << foo2() << foo3()
выглядит как
<<
/ \
<< foo3()
/ \
<< foo2()
/ \
std::cout foo1()
Опять функции foo
могут быть оценены в любом порядке, но порядок оценок operator<<()
определен корректно. Есть интересный пост о точках последовательности, который очень хорошо описывает темы.