我是一个相当称职的C ++用户(不是一个完整的菜鸟)。我有一个充当资源句柄的类。这个类有一个移动构造函数和复制construtor被删除是有道理的:
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使用它。
我有另一个类vector
Foo
:
struct Bar { // (Constructor added below)
std::vector<Foo> foos;
};
我想为Bar
编写一个构造函数,调用者在vector<Foo>
中传递。我希望调用者提供的整个向量被移动到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
的复制构造函数。
如何将vector<Foo>
的右值引用'vf'直接赋予'foos'的构造函数?
答案 0 :(得分:8)
命名参数不是右值,因此您必须通过调用vf
将std::move
转换为右值参考:
Bar(std::vector<Foo>&& vf) : foos(std::move(vf) {}
另外,如果用户必须调用std::move
来获取rvalue参数,那就不正确了。当参数是函数的返回值时,不需要std::move
,这是rvalue的经典概念。
答案 1 :(得分:0)
通常,如果您有一个仅移动类型的参数,则按值:
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());