关于这个问题
C 17介绍的评估顺序是什么?
使用此规范
http://www.open-std.org/jtc1/sc22/wg21/wg21/docs/papers/2016/p0145r3.pdf
和规格中的本文
此外,我们建议以下其他规则: 评估涉及超载操作员的表达是 由与相应内置的顺序确定 运算符,而不是函数调用规则。
这是否意味着这两个表达式不再等效?
a << b;
operator<<(a, b);
作为第二个函数调用,因此参数中没有保证的评估顺序?
"作为第二个函数调用,因此参数中没有保证的评估顺序?"
确实。[expr.call]/5包含一个示例,专门涵盖了您的问题中涵盖的两个情况之间的区别[强调我的]:
在每个表达式之前,将后缀表达在 表达列表和任何默认参数。一个初始化 参数,包括每个关联的值计算和侧面 效果,相对于任何其他 参数。
...
注意:如果使用操作员符号调用操作员函数, 参数评估已按照为内置的指定进行测序 操作员;看 [over.match.oper]。 [示例:
struct S { S(int); }; int operator<<(S, int); int i, j; int x = S(i=1) << (i=2); int y = operator<<(S(j=1), j=2);
执行初始化后,
i
的值为2
(请参阅 [expr.shift]),但是是未指定的j
的值是否为1
或2
。- 结束示例]