如何获取右值引用参数并将其传递到其他地方?
How to take an rvalue reference parameter and pass it on elsewhere?
我是一个相当称职的 C++ 用户(不是完全的菜鸟)。我有一个 class 作为资源句柄。 class 有一个移动构造函数和复制构造函数被删除是有意义的:
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 的使用率。
我有另一个 class 保持 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
.[=26= 的复制构造函数]
如何将 'vf' 的 vector<Foo>
的右值引用直接提供给 'foos' 的构造函数?
命名参数不是右值,因此您必须通过调用 std::move
:
将 vf
转换为右值引用
Bar(std::vector<Foo>&& vf) : foos(std::move(vf) {}
此外,说用户 必须 调用 std::move
以获得右值参数是不正确的;当参数是函数的 return 值时,不需要 std::move
,这是右值的经典概念。
通常,当你有一个只移动类型的参数时,你按值取它:
struct Bar
{
std::vector<Foo> foos;
Bar(vector<Foo> vf) :
foos(std::move(vf)a) {}
};
这会强制调用者写入
Bar x(std::move(y));
这表明 y
的所有权已放弃。
此外,调用者可以毫不费力地传递函数的 return 值:
Bar x(get_me_some_Foos());
我是一个相当称职的 C++ 用户(不是完全的菜鸟)。我有一个 class 作为资源句柄。 class 有一个移动构造函数和复制构造函数被删除是有意义的:
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 的使用率。
我有另一个 class 保持 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
.[=26= 的复制构造函数]
如何将 'vf' 的 vector<Foo>
的右值引用直接提供给 'foos' 的构造函数?
命名参数不是右值,因此您必须通过调用 std::move
:
vf
转换为右值引用
Bar(std::vector<Foo>&& vf) : foos(std::move(vf) {}
此外,说用户 必须 调用 std::move
以获得右值参数是不正确的;当参数是函数的 return 值时,不需要 std::move
,这是右值的经典概念。
通常,当你有一个只移动类型的参数时,你按值取它:
struct Bar
{
std::vector<Foo> foos;
Bar(vector<Foo> vf) :
foos(std::move(vf)a) {}
};
这会强制调用者写入
Bar x(std::move(y));
这表明 y
的所有权已放弃。
此外,调用者可以毫不费力地传递函数的 return 值:
Bar x(get_me_some_Foos());