C++ 使用移动语义的初始值设定项列表顺序中的未定义行为

C++ 使用移动语义的初始值设定项列表顺序中的未定义行为,c++,c++11,move-semantics,C++,C++11,Move Semantics,是(1)未定义的行为,还是始终首先计算对的第一个元素 #包括 #包括 整型条(标准::数组&&){ 返回1; } std::pair foo(){ std::数组a; 返回{a,bar(std::move(a))};//(1) } 作为旁注,使用返回make_对(a,bar(std::move(a))是不同的?您可能会看到规则 10) 在列表初始化中,给定初始值设定项子句的每个值计算和副作用在与初始值设定项子句后面的任何初始值设定项子句相关联的每个值计算和副作用之前,在括号内逗号分隔的初始值设

是(1)未定义的行为,还是始终首先计算对的第一个元素

#包括
#包括
整型条(标准::数组&&){
返回1;
}
std::pair foo(){
std::数组a;
返回{a,bar(std::move(a))};//(1)
}
作为旁注,使用
返回make_对(a,bar(std::move(a))是不同的?

您可能会看到规则

10) 在列表初始化中,给定初始值设定项子句的每个值计算和副作用在与初始值设定项子句后面的任何初始值设定项子句相关联的每个值计算和副作用之前,在括号内逗号分隔的初始值设定项列表中排序

所以

return { a, bar(std::move(a)) };
首先计算
a
,然后计算
bar(std::move(a))

作为旁注,使用
返回make_对(a,bar(std::move(a))而不是不同

是的,这是一个函数调用,计算顺序未指定。它本身不是UB,但如果一个订单导致UB,则可以导致UB。 在您的情况下,两个订单都可以,并且给出相同的结果

C++17还增加了该限制:

15) 在函数调用中,每个参数初始化的值计算和副作用相对于任何其他参数的值计算和副作用是不确定的

你可能会看到规则

10) 在列表初始化中,给定初始值设定项子句的每个值计算和副作用在与初始值设定项子句后面的任何初始值设定项子句相关联的每个值计算和副作用之前,在括号内逗号分隔的初始值设定项列表中排序

所以

return { a, bar(std::move(a)) };
首先计算
a
,然后计算
bar(std::move(a))

作为旁注,使用
返回make_对(a,bar(std::move(a))而不是不同

是的,这是一个函数调用,计算顺序未指定。它本身不是UB,但如果一个订单导致UB,则可以导致UB。 在您的情况下,两个订单都可以,并且给出相同的结果

C++17还增加了该限制:

15) 在函数调用中,每个参数初始化的值计算和副作用相对于任何其他参数的值计算和副作用是不确定的


无论如何,这两种情况都不会发生。“移动自”仍处于有效状态。无论如何,这两种情况下都不会发生。已移动的发件人仍处于有效状态。