在这种情况下完美转发

时间:2014-05-11 19:14:01

标签: c++11 perfect-forwarding

我目前正在阅读有关完美转发的内容,并指出完美转发的目的是将左值作为左值和右值作为右值传递。所以我使用以下示例来了解完美转发。这里的foo对象有一个复制和移动cnstr,它还有一个复制和移动赋值运算符。

void mfoo(foo arg)
{
    .......
}


template<typename T>
void relay(T&& arg)
{
    mfoo(std::forward<T>(arg));
}


//Start here
foo f;
relay(std::move(f));

现在我在VS2012中测试此代码,移动构造函数只调用一次。我期待它被召唤两次。如果有人能向我解释,我将不胜感激。 我期望在中继处调用第一个移动构造函数,并在mfoo

调用下一个移动构造函数

1 个答案:

答案 0 :(得分:2)

//Start here
foo f; // default-initialize `f`, call the default constructor
relay(std::move(f));
  • std::move(f)static_cast<foo&&>(f)的效果相同,所以实际上并没有&#34;做&#34;任何事情;它只产生一个右值表达式(&#34; f被视为右值&#34;)。

  • relay( std::move(f) )实例化void relay<foo>(foo&& arg)并调用此函数。该参数是参数,与参数兼容,因此不会调用构造函数。


mfoo(std::forward<T>(arg))
    如果std::forward<T>(arg)是左值引用,则
  • arg会将T作为左值,如果T不是左值引用,则会将其作为右值。即,对于T == foo&&,它与std::move(arg)的作用相同。没有构造函数被调用。

  • mfoo(..)最后调用mfoo,它的参数的值为。这会导致复制或移动,具体取决于参数表达式的类型和值类别。

由于我们的参数表达式是一个右值,因此将调用移动构造函数(如果存在且可访问)。