C++ 什么时候可以在函数和它的参数之间交织未排序的代码?

C++ 什么时候可以在函数和它的参数之间交织未排序的代码?,c++,c++11,C++,C++11,假设我有类型T和U,函数uf(T)和tg(),我写表达式f(g())。在什么情况下,附近未排序表达式中的代码可能在g之后但在f之前执行 我知道有一种情况是在函数调用中,例如h(f(g()),j()),j可以在与g和f相关的任何时间执行。这基本上是唯一的例子,还是还有其他例子 出于动机,可以使用函数std::make_shared和std::make_unique编写更多异常安全代码,如以下不安全代码示例所示: //在某些头文件中: 无效f(标准::唯一的ptr,标准::唯一的ptr); //在某

假设我有类型
T
U
,函数
uf(T)
tg()
,我写表达式
f(g())
。在什么情况下,附近未排序表达式中的代码可能在
g
之后但在
f
之前执行

我知道有一种情况是在函数调用中,例如
h(f(g()),j())
j
可以在与
g
f
相关的任何时间执行。这基本上是唯一的例子,还是还有其他例子

出于动机,可以使用函数
std::make_shared
std::make_unique
编写更多异常安全代码,如以下不安全代码示例所示:

//在某些头文件中:
无效f(标准::唯一的ptr,标准::唯一的ptr);
//在某些呼叫站点:
f(std::unique_ptr{new T1},std::unique_ptr{new T2});
T2
构造函数可能会在
T1
构造函数之后但在
std::unique_ptr
构造函数之前抛出异常,导致
T1
泄漏。解决方法是编写
f(make_unique(),make_unique())取而代之


我发现关于std::unique\u ptr所提供的异常安全性的每次讨论都使用相同的示例。这让我想知道多个参数函数中的参数表达式(包括某些运算符,如
+
[]
)是否是唯一可以预期这种行为的情况。

[intro.execution]
(§1.9)包含规则,这些规则实际上非常简单

14在与下一个待计算的完整表达式相关的每个值计算和副作用之前,对与完整表达式相关的每个值计算和副作用进行排序

15除非另有说明,否则对单个运算符的操作数和单个表达式的子表达式的求值是不排序的


完整表达式就是它所说的:不是任何其他表达式的子表达式的表达式。因此,只有一个表达式的子表达式可以取消排序,而不是全部。例如,某些运算符对其参数的执行进行排序,而函数调用的顺序是不确定的(即不是交错的)。

[intro.execution]
(§1.9)包含规则,这些规则实际上非常简单

14在与下一个待计算的完整表达式相关的每个值计算和副作用之前,对与完整表达式相关的每个值计算和副作用进行排序

15除非另有说明,否则对单个运算符的操作数和单个表达式的子表达式的求值是不排序的


完整表达式就是它所说的:不是任何其他表达式的子表达式的表达式。因此,只有一个表达式的子表达式可以取消排序,而不是全部。例如,某些操作符对它们的参数的执行顺序进行排序,函数调用是不确定地排序的(即,不是交错的)。< /P>除非任何指定,否则任何完整表达式的所有子表达式的求值顺序都是未指定的。如果您认为操作符是函数调用,然后,每个表达式都是嵌套函数调用的树。你已经通过问题陈述定义了所有的备选方案;另请参见不确定的操作员。任何操作符,除了那些显式排序求值的操作符(&&、| |、?:、逗号,在所有情况下,除非重载。)@igortandtnik如果这是答案,那太好了!我更担心C++语言中有一些地方,除了一个更大的表达式的子表达式,我没有想到。我知道初始值设定项列表是按顺序排列的,变量声明是按顺序排列的,完整语句是按顺序排列的。。。但是我们还需要担心什么呢?除非完全指定,任何完整表达式的所有子表达式的评估顺序都是未指定的。如果你认为运算符是函数调用,那么每个表达式都是嵌套函数调用树。你已经通过问题陈述定义了所有的备选方案;另请参见不确定的操作员。任何操作符,除了那些显式排序求值的操作符(&&、| |、?:、逗号,在所有情况下,除非重载。)@igortandtnik如果这是答案,那太好了!我更担心C++语言中有一些地方,除了一个更大的表达式的子表达式,我没有想到。我知道初始值设定项列表是按顺序排列的,变量声明是按顺序排列的,完整语句是按顺序排列的。。。但我们还需要担心什么呢?
// In some header file:
void f( std::unique_ptr<T1>, std::unique_ptr<T2> );

// At some call site:
f( std::unique_ptr<T1>{ new T1 }, std::unique_ptr<T2>{ new T2 } );