我设置了一个测试用例来了解完美转发。
std::string inner(const std::string& str ) {
return "const std::string&";
}
std::string inner(std::string& str ) {
return "std::string&";
}
std::string inner(const std::string&& str ) {
return "const std::string&&";
}
std::string inner(std::string&& str ) {
return "std::string&&";
}
template <typename T> void outer(T&& t) {
std::cout << "t: " << t << std::endl;
std::cout << "perfect forward: " << inner(std::forward<T>(t)) << std::endl;
std::cout << std::endl;
}
void PerfectForwarding()
{
outer("literal");
outer(lvalue);
outer(constlvalue);
outer(rvalue());
outer(constrvalue());
}
std::forward
按预期工作。当我在没有身份的情况下实现自己的转发函数时,会出现有趣的行为:
template <typename T> T&& MyForward(T& t)
{
return ((T&&)t);
}
std::forward
用in outer替换MyForward
会得到完全相同的结果!这种行为引出了一个问题,为什么要使用身份?
编译器VS2010
更新 1:关于防止类型推断
AFAIK,特殊类型扣除规则仅在 T&& 上激活。注意 forward 的定义,forward(typename identity<T>::type& t)
。参数类型只有一个 &。事实上,在我将 MyForward 更改为使用身份并省略 (T&&) 强制转换后,该示例无法编译。从表面上看,从左值到右值的转换似乎使正向工作。
更新 2:在 ideone.com 上使用 GCC 4.5 进行了测试,行为相同。