这是右值引用的正确用法吗?
Is this a correct usage of rvalue references?
考虑以下函数:
vector<int> get_vector()
{
vector<int> xs;
// Do some stuff to fill the vector with numbers...
return xs;
}
改为编写以下内容是否有意义?主要目标是避免在返回向量时复制向量。
vector<int>&& get_vector()
{
vector<int> xs;
// Do some stuff to fill the vector with numbers...
return std::move(xs);
}
除了避免复制之外,是否存在任何语义差异?
是的,有区别。考虑以下情况:
std::vector<int> v = get_vector();
对于第一种情况,我们可以进行命名return值优化。这意味着局部变量xs
实际上是要在v
中in place构造。这里根本不会有任何动作。这是尽可能高效的。
第二种情况,xs
不得不在本地构建,这样才能搬出。 NRVO是不可能的,所以才会有举动。所以这更糟。
现在考虑以下情况:
auto&& v = get_vector();
在第一种情况下,这是可以的。 get_vector()
return 是一个临时的,它绑定到引用并延长 v
的生命周期。
在第二种情况下,我们只是引用了临时 xs
,现在有一个悬空引用。这很糟糕。
总而言之:总是更喜欢 return 当地人的价值。从调用者的角度来看,它们 已经 右值,因此显式地使它们成为右值引用没有任何优势。
没有副本。如果可以,调用者将移动它。此外,在第二个中,您返回了对本地的引用,这很糟糕。
考虑以下函数:
vector<int> get_vector()
{
vector<int> xs;
// Do some stuff to fill the vector with numbers...
return xs;
}
改为编写以下内容是否有意义?主要目标是避免在返回向量时复制向量。
vector<int>&& get_vector()
{
vector<int> xs;
// Do some stuff to fill the vector with numbers...
return std::move(xs);
}
除了避免复制之外,是否存在任何语义差异?
是的,有区别。考虑以下情况:
std::vector<int> v = get_vector();
对于第一种情况,我们可以进行命名return值优化。这意味着局部变量xs
实际上是要在v
中in place构造。这里根本不会有任何动作。这是尽可能高效的。
第二种情况,xs
不得不在本地构建,这样才能搬出。 NRVO是不可能的,所以才会有举动。所以这更糟。
现在考虑以下情况:
auto&& v = get_vector();
在第一种情况下,这是可以的。 get_vector()
return 是一个临时的,它绑定到引用并延长 v
的生命周期。
在第二种情况下,我们只是引用了临时 xs
,现在有一个悬空引用。这很糟糕。
总而言之:总是更喜欢 return 当地人的价值。从调用者的角度来看,它们 已经 右值,因此显式地使它们成为右值引用没有任何优势。
没有副本。如果可以,调用者将移动它。此外,在第二个中,您返回了对本地的引用,这很糟糕。