答案取决于您使用的是哪个版本的 C++ 标准(或您的编译器正在使用)。
C++ 2003 5.2.2 p8 说:
参数的评估顺序未指定。参数表达式评估的所有副作用在输入函数之前生效。后缀表达式和参数表达式列表的求值顺序未指定。
这意味着在评估和之间没有序列点。f(x)
args
在 C++ 2011 中,序列点的整个概念已被替换(参见N1944),该措辞现在只是一个注释:
[注意:后缀表达式和参数表达式的计算相对于彼此都是无序的。参数表达式求值的所有副作用都在输入函数之前排序(见 1.9)。——尾注]
和 1.9 p15 说
调用函数时(无论该函数是否内联),与任何参数表达式或与指定被调用函数的后缀表达式相关的每个值计算和副作用都在执行主体中的每个表达式或语句之前进行排序称为函数。[注意:与不同参数表达式相关的值计算和副作用是无序的。——尾注]
这表示表达式f(x)
和表达式args
在 的主体中的所有内容之前排序g
,但它们相对于彼此是无序的,这与 C++03 规则相同,但措辞不同。
C++14 与 C++11 具有相同的规则,但正如下面评论中所指出的,C++17 中的规则发生了变化。
C++ 2017 8.2.2 [expr.call] p5 说:
后缀表达式在表达式列表中的每个表达式和任何默认参数之前排序。参数的初始化,包括每个相关的值计算和副作用,相对于任何其他参数的初始化是不确定的。
这意味着对于您的示例,将按顺序执行以下步骤:
f
被评估。
x
被评估并且参数f
被初始化。
f(x)
评估函数调用。
f(x)->g
被评估。
args
并且其他参数g
被评估并且参数g
被初始化(以未指定的顺序)。
- 最后,
f(x)->g(args, ...)
评估函数调用。