参数评估后参数绑定是否排序?

时间:2011-08-29 11:03:37

标签: c++ parameter-passing evaluation c++11 move-semantics

假设我有以下功能:

void foo(std::vector<int> vec, int n);

如果我按这样调用函数:

std::vector<int> numbers { 2, 3, 5, 7, 11, 13, 17, 19 };
foo(std::move(numbers), numbers[0]);

在绑定参数之前是否完全评估了所有参数?在这种情况下,std::move是无害的,因为它只会产生一个引用numbers的x值。或者,一旦评估,每个单独的参数是否可以立即绑定到其参数?在这种情况下,numbers[0]可能会导致未定义的行为,因为numbers可能已经被移入vec

1 个答案:

答案 0 :(得分:10)

在§1.9/ 15上,我们被告知:

  

调用函数时(无论函数是否为内联函数),每个值计算和副作用   与任何参数表达式相关联,或与指定被调用函数的后缀表达式相关联   在执行被调用函数体内的每个表达式或语句之前进行排序。 (...)

关于§5.2.2/ 4:

  

(...)每个参数的初始化和销毁​​都发生在。的上下文中   调用功能。 (...)

我在最终草案中找不到任何其他相关文字。由于这没有在参数评估和参数初始化之间明确定义之前的关系序列,因此它们未排序并且std::move不是无害的。

此问题的解决方案是强制使用临时变量的序列:

std::vector<int> numbers { 2, 3, 5, 7, 11, 13, 17, 19 };
int num = numbers[0];
foo(std::move(numbers), num);