第一个例子
std::vector<int> return_vector(void)
{
std::vector<int> tmp {1,2,3,4,5};
return tmp;
}
std::vector<int> &&rval_ref = return_vector();
第一个示例返回一个临时值,该临时值被捕获rval_ref
。那个临时的生命将延长到超越rval_ref
定义,您可以使用它,就像您通过值捕获它一样。这与以下内容非常相似:
const std::vector<int>& rval_ref = return_vector();
除了在我的重写中你显然不能使用rval_ref
以非常量的方式。
第二个例子
std::vector<int>&& return_vector(void)
{
std::vector<int> tmp {1,2,3,4,5};
return std::move(tmp);
}
std::vector<int> &&rval_ref = return_vector();
在第二个示例中,您创建了一个运行时错误。rval_ref
现在持有对被破坏的引用tmp
函数内部。运气好的话,这段代码会立即崩溃。
第三个例子
std::vector<int> return_vector(void)
{
std::vector<int> tmp {1,2,3,4,5};
return std::move(tmp);
}
std::vector<int> &&rval_ref = return_vector();
您的第三个示例大致相当于您的第一个示例。这std::move
on tmp
是不必要的,实际上可能是性能悲观,因为它会抑制返回值优化。
编写您正在做的事情的最佳方法是:
最佳实践
std::vector<int> return_vector(void)
{
std::vector<int> tmp {1,2,3,4,5};
return tmp;
}
std::vector<int> rval_ref = return_vector();
IE。就像在 C++03 中一样。tmp
在 return 语句中被隐式地视为右值。它将通过返回值优化返回(不复制,不移动),或者如果编译器决定它不能执行 RVO,那么它将使用向量的移动构造函数来执行返回。仅当不执行 RVO,并且返回的类型没有移动构造函数时,才会使用复制构造函数进行返回。