我目前正试图找出完美转发的工作原理。我已经编写了一段示例代码,据我所知,它执行完美的转发,因为它应该是:
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
现在,我的问题是:这两个替代版本会做什么,并且在任何可能的背景下它们都有意义吗?与上述“正确”版本中的参考折叠规则相比,参考折叠规则如何应用?
答案 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
成为&&
。