Rvalue ref和完美转发

时间:2011-07-28 16:50:50

标签: c++ c++11 rvalue-reference perfect-forwarding

我读过几篇关于&&和我只是好奇,如果有:

void fnc_1(int&& p)
{
//...
}

void fnc(int&& r)
{
fnc_1(r);//am I suppose to/should I? call it like so:fnc_1(std::forward(r)) 
}

或只是传递'r'就足够了?

2 个答案:

答案 0 :(得分:6)

fnc_1(r)将无法编译,因为r是一个左值,就像任何其他变量一样,无论类型如何。是的,没错,名为右值的引用是左值,而不是右值。

fnc_1(std::forward(r))也不会编译,因为std::forward专门设计为不推断其模板参数。

要传递右值,以下任何一种都可以使用:

fnc_1(std::move(r))
fnc_1(std::forward<int&&>(r))  
fnc_1(std::forward<int>(r))  

使用std::move是将左值转换为右值的惯用方法,因此我建议使用它。

答案 1 :(得分:3)

std::forward模板通常用于依赖类型。请仔细阅读this question,看看它是否适用于此处。这是一个难以掌握的主题,因此请随时使用有关您确切问题的相关详细信息更新您的问题(使用整数的rvalue引用并不是非常令人兴奋......)。

我相信你的问题是关于rvalue引用的基本属性的理解。要记住的经验法则是:

  • 任何名称都是左值(常量或非常量)。
  • 任何没有名字的人都是右撇子。
  • &&的类型绑定到右值。

如果你有一个功能...

void foo(SomeClass&& x)
{
    // ... then here x has type SomeClass& !
}

然后在正文中,x是一个名称,因此是 l 值。它确实有SomeClass&类型。您必须使用std::moveSomeClass&变为SomeClass&&

void bar(SomeClass&& x)
{
    // Since `x` has a name here, it is a Lvalue.
    // Therefore it has type SomeClass&, what the signature doesn't indicate.

    // We thus have to explicitly turn it into a rvalue:
    foo(std::move(x));
}