完美转发和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
变成 &&
。
我目前正在尝试弄清楚完美转发的工作原理。我已经编写了一段示例代码,据我所知,它可以执行完美的转发,因为它应该是:
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
变成 &&
。