考虑以下代码:
std::vector<int> Foo() {
std::vector<int> v = Bar();
return v;
}
return v
是 O(1),因为 NRVO 将省略复制,v
直接在存储中构造函数的返回值,否则函数的返回值将被移动或复制到. 现在考虑功能类似的代码:
void Foo(std::vector<int> * to_be_filled) {
std::vector<int> v = Bar();
*to_be_filled = v;
}
可以在这里提出一个类似的论点,*to_be_filled = v
可以想象它可以编译为 O(1) 移动分配,因为它是一个超出范围的局部变量(编译器应该很容易验证其中v
没有外部引用这种情况,因此在最后一次使用时将其提升为右值)。是这样吗?有一个微妙的原因吗?
此外,感觉这种模式可以扩展到左值超出范围的任何上下文:
void Foo(std::vector<int> * to_be_filled) {
if (Baz()) {
std::vector<int> v = Bar();
*to_be_filled = v;
}
...
}
期望编译器找到诸如 the 之类的模式*to_be_filled = v
,然后自动优化它们以假设右值语义,是否/可以/是否有用/合理?
编辑:
g++ 7.3.0在 -O3 模式下不执行任何此类优化。