完美的Fowarding和std :: forward <t>的使用

时间:2017-02-22 11:29:58

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

我目前正试图找出完美转发的工作原理。我已经编写了一段示例代码,据我所知,它执行完美的转发,因为它应该是:

void whatIsIt(std::vector<int>&& variable)
{
  std::cout << "rvalue" << std::endl;
}

void whatIsIt(std::vector<int>& variable)
{
  std::cout << "lvalue" << std::endl;
}

template <class T>
void performPerfectForwarding(T&& variable)
{
  whatIsIt(std::forward<T>(variable));
}

int main(int argc, char** argv)
{
  std::vector<int> lvalue;
  performPerfectForwarding(lvalue);
  performPerfectForwarding(std::move(lvalue));

  return 0;
}

使用左值调用函数performPerfectForwarding使其调用whatIsIt的相应重载,同样适用于使用右值调用它。因此,此代码生成的输出为:

lvalue
rvalue

但是,我问自己函数performPerfectForwarding的以下版本会做什么:

1

template <class T>
void performPerfectForwarding(T& variable)
{
  whatIsIt(std::forward<T>(variable));
}

2

template <class T>
void performPerfectForwarding(T variable)
{
  whatIsIt(std::forward<T>(variable));
}

他们都输出:

rvalue
rvalue

现在,我的问题是:这两个替代版本会做什么,并且在任何可能的背景下它们都有意义吗?与上述“正确”版本中的参考折叠规则相比,参考折叠规则如何应用?

1 个答案:

答案 0 :(得分:8)

template <class T>
void performPerfectForwarding(T& variable)
{
    whatIsIt(std::forward<T>(variable));
}

variable不是转发参考时,即使 lvalues T也会被推断为T(与推断为T&相对应。因此,这会将variable转换为右值引用,因为:

forward<T> -> T&&
forward<T&> -> T&
forward<T&&> -> T&&
template <class T>
void performPerfectForwarding(T variable)
{
    whatIsIt(std::forward<T>(variable));
}

同样的考虑适用于此。此处T永远不能是左值参考,因此forward将始终转换为右值参考

  

这两个替代版本会做什么,在任何可能的背景下它们都有意义吗?

我不这么认为,因为您的forward基本上是move

  

参考折叠规则如何适用于这些情况,而不是它们如何应用于上述&#34;正确&#34;版本

这些规则照常应用。记住:

&  &  -> &
&  && -> &
&& &  -> &
&& && -> &&

在这两种情况下都无法让variable成为&&