Ответ 1
Вы правы, и интервьюер показывает пугающе распространенное отсутствие понимания языка и его правил.
Эти две строки строго эквивалентны, если каждый operator<<
, вызываемый для первой строки, всегда является свободной функцией (стандарт говорит, что они есть).
Как вы правильно поняли, упорядочение между вызовами функций, за исключением тех случаев, когда одни аргументы являются возвращаемым значением другого, неопределенно упорядочено (до или после, но не указано):
1.9 Выполнение программы
[intro.execution]
[...]
15 [...]
При вызове функции (независимо от того, является ли функция встроенной) каждое вычисление значения и побочный эффект, связанные с любым выражением аргумента, или с выражением postfix, обозначающим вызываемую функцию, секвенированы перед выполнением каждого выражения или выражения в теле называемой функцией. [Примечание. Вычисления значений и побочные эффекты, связанные с разными выражениями аргументов, не имеют никакого значения. -end note] Каждая оценка в вызывающей функции (включая другие вызовы функций), которая иначе не секретируется отдельно до или после выполнения тела вызываемой функции, неопределенно упорядочена в отношении выполнения вызываемая функция .9 Несколько контекстов в С++ вызывают оценку вызова функции, даже если в блоке перевода не появляется синтаксис соответствующих функций. [Пример: оценка нового выражения вызывает одну или несколько функций распределения и конструктора; см. 5.3.4. Для другого примера, вызов функции преобразования (12.3.2) может возникать в контекстах, в которых не появляется синтаксис вызова функции. -end example] Ограничения последовательности для выполнения вызываемой функции (как описано выше) являются функциями вызовов функций, которые оцениваются, независимо от того, какой синтаксис выражения, вызывающего функцию, может быть.
Именование всех частей:
cout << one() // a) execute one() ("one\n")
// b) output the return-value ("1")
<< '\n' // c) output newline ("\n")
<< two() // d) execute two() ("two\n")
// e) output the return-value ("2")
<< '\n'; // f) output newline ("\n")
Ограничения для заказа:
a < b < c < e < f
d < e < f
Или другое представление:
a < b < c <
< e < f
d <
Таким образом, все действительные полные порядки:
abcdef "one\n1\ntwo\n2\n"
abdcef "one\n1two\n\n2\n"
adbcef "one\ntwo\n1\n2\n"
dabcef "two\none\n1\n2\n"