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

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 保持 vectorFoo:

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