如何获取右值引用参数并将其传递到其他地方?

How to take an rvalue reference parameter and pass it on elsewhere?

本文关键字:其他 参数 何获取 获取 引用      更新时间:2023-10-16

我是一个相当称职的C++用户(不是一个完全的菜鸟)。我有一个充当资源句柄的类。 类具有移动构造函数并删除复制构造器是有意义的:

struct Foo {
Foo (int i) : // For sake of example.
x(i)
{}
Foo (Foo && f) :
x(f.x)
{
f.x = 0; // 0 is special and means "moved from".
}
Foo (const Foo & f) = delete;
private:
int x;
};

多年来,我一直以货物崇拜的方式这样做,而且效果很好。 现在我正试图用我的 C++11 来加强档次。

我还有另一个类可以保持Foovector

struct Bar { // (Constructor added below)
std::vector<Foo> foos;
};

我想为调用者在vector<Foo>中传递Bar编写一个构造函数。 我希望将调用方提供的整个向量移动到Bar.foos中。 我想通过使构造函数参数成为vector<Foo>&&而不是普通vector<Foo>&来向调用者明确这一点。 这样,调用方必须将向量std::move到构造函数中。

int main (int argc, char ** argv)
{     
Foo f1 (1);
Foo f2 (2);
std::vector<Foo> v;
v.push_back (std::move(f1));
v.push_back (std::move(f2));
Bar b (std::move(v)); // I want the user to HAVE TO std::move v.
return 0;
}

我天真地尝试像这样编写Bar构造函数:

struct Bar {
Bar (vector<Foo> && vf) :
foos (vf) // pass the rvalue reference into foos' constructor, right?
{}
std::vector<Foo> foos;
};

我的电脑有 g++ 4.9.2 和 clang++ 3.5.0,它们都给了我一个小的错误爆炸。 他们都尝试使用矢量复制构造函数构造Bar.foos,然后失败,因为我删除了Foo的复制构造函数。

如何直接将 'ff'(vector<Foo>的右值引用)提供给 'foos' 的构造函数?

命名参数不是右值,因此您必须通过调用std::movevf转换为右值引用:

Bar(std::vector<Foo>&& vf) : foos(std::move(vf) {}

此外,说用户必须为 rvalue 参数调用std::move并不完全正确;当参数是函数的返回值时,不需要std::move,这是 rvalue 的经典概念。

通常,当您具有仅移动类型的参数时,您可以按值获取它:

struct Bar
{
std::vector<Foo> foos;
Bar(vector<Foo> vf) :
foos(std::move(vf)a) {}
};

这会强制调用方写入

Bar x(std::move(y));

这清楚地表明放弃了y的所有权。 此外,调用方可以只传递函数的返回值,无需进一步操作:

Bar x(get_me_some_Foos());