13

假设我有以下功能:

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是无害的,因为它只产生一个引用 的 xvalue numbers。或者每个单独的参数是否可以在评估后立即绑定到它的参数?在这种情况下,numbers[0]可能会导致未定义的行为,因为numbers可能已经被移入vec.

4

1 回答 1

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);
于 2011-08-29T11:19:38.650 回答