这是右值引用的正确用法吗?

Is this a correct usage of rvalue references?

本文关键字:用法 引用      更新时间:2023-10-16

考虑以下函数:

vector<int> get_vector()
{
    vector<int> xs;
    // Do some stuff to fill the vector with numbers...
    return xs;
}

这样写有意义吗?主要目标是在返回vector时避免复制vector。

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();

在第一种情况下,我们可以执行命名返回值优化。这意味着局部变量xs实际上将在v中的位置构造。这里什么也不许动。这是尽可能高效的。

在第二种情况下,xs 必须在本地构建,以便将其移出。NRVO是不可能的,所以会有行动。所以这更糟糕。

现在考虑以下情况:

auto&& v = get_vector();

在第一种情况下,这是可以的。get_vector()返回一个临时对象,它被绑定到引用,并在v的生命周期内扩展。

在第二种情况下,我们只是对临时xs的引用,现在有一个悬垂引用。

总而言之:总是倾向于按值返回局部变量。从调用者的角度来看,它们已经是右值,因此显式地使它们成为右值引用没有任何好处。

没有副本。如果可以的话,呼叫者会移动它。此外,在第二个示例中,您返回了对局部的引用,这很糟糕。