完美转发和std::forward<T>的使用

Perfect Fowarding and the Use of std::forward<T>

我目前正在尝试弄清楚完美转发的工作原理。我已经编写了一段示例代码,据我所知,它可以执行完美的转发,因为它应该是:

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

现在,我的问题是:这两个替代版本会做什么,它们在任何可能的上下文中是否有意义?与它们在上述 "correct" 版本中的应用相比,参考折叠规则在这些情况下如何应用?

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

variable 不是 forwarding-reference 时,即使对于 lvalues[,T 也被推断为 T =46=] (对比推导为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 将始终转换为 右值引用 .


What would these two alternative versions do and would they make sense in any possible context?

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


How do the reference collapsing rules apply in these cases compared to how they apply in the aforementioned "correct" version?

此处照常应用规则。记住:

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

在这两种情况下都没有办法让 variable 变成 &&