具有运算符重载函数的 c++17 评估顺序
c++17 evaluation order with operator overloading functions
关于这个问题
有这个规格
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0145r3.pdf
以及规范中的这段文字
Furthermore, we suggest the following additional rule: the order of
evaluation of an expression involving an overloaded operator is
determined by the order associated with the corresponding built-in
operator, not the rules for function calls.
这是否意味着这两个表达式不再等价?
a << b;
operator<<(a, b);
由于第二个看起来像一个函数调用,因此参数中的评估顺序没有保证?
"As the second one looks like a function call, hence there is no guaranteed evaluation order in the parameters?"
确实如此。 [expr.call]/5 包含一个示例,具体说明了您的问题中涵盖的两种情况之间的区别 [强调我的 ]:
The postfix-expression is sequenced before each expression in the
expression-list and any default argument. The initialization of a
parameter, including every associated value computation and side
effect, is indeterminately sequenced with respect to that of any other
parameter.
...
Note: If an operator function is invoked using operator notation,
argument evaluation is sequenced as specified for the built-in
operator; see
[over.match.oper].
[ Example:
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);
After performing the initializations, the value of i
is 2
(see
[expr.shift]), but it is unspecified whether the value of j
is
1
or 2
.
— end example ]
关于这个问题
有这个规格
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0145r3.pdf
以及规范中的这段文字
Furthermore, we suggest the following additional rule: the order of evaluation of an expression involving an overloaded operator is determined by the order associated with the corresponding built-in operator, not the rules for function calls.
这是否意味着这两个表达式不再等价?
a << b;
operator<<(a, b);
由于第二个看起来像一个函数调用,因此参数中的评估顺序没有保证?
"As the second one looks like a function call, hence there is no guaranteed evaluation order in the parameters?"
确实如此。 [expr.call]/5 包含一个示例,具体说明了您的问题中涵盖的两种情况之间的区别 [强调我的 ]:
The postfix-expression is sequenced before each expression in the expression-list and any default argument. The initialization of a parameter, including every associated value computation and side effect, is indeterminately sequenced with respect to that of any other parameter.
...
Note: If an operator function is invoked using operator notation, argument evaluation is sequenced as specified for the built-in operator; see [over.match.oper]. [ Example:
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);
After performing the initializations, the value of
i
is2
(see [expr.shift]), but it is unspecified whether the value ofj
is1
or2
.— end example ]