Can*_*hiu 12 c++ visual-studio-2010 visual-c++ c++11
我设置了一个测试用例来了解完美转发.
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());
}
Run Code Online (Sandbox Code Playgroud)
std::forward按预期工作.当我实现我自己的没有身份的转发函数时,有趣的行为出现了:
template <typename T> T&& MyForward(T& t)
{
return ((T&&)t);
}
Run Code Online (Sandbox Code Playgroud)
更换std::forward用MyForward外给完全相同的结果!这种行为引出了为什么使用身份的问题?
编译器VS2010
更新1:参考防止类型扣除
AFAIK,特殊类型扣除规则仅在T &&上激活.注意forward的定义forward(typename identity<T>::type& t).参数类型只有一个&.实际上,在我将MyForward更改为使用标识并省略(T &&)转换后,该示例无法编译.从表面上看,从左值到右值的铸造似乎使前进工作.
更新2:在ideone.com上使用GCC 4.5测试,行为相同.
R. *_*des 13
remove_reference<T>(identity在草稿的旧版本中,但更改为remove_reference)用于防止类型推导:std::forward 仅适用于显式类型参数.否则以下将编译:
std::forward(t)
Run Code Online (Sandbox Code Playgroud)
......但它不会做正确的事情.
关于与左值/右值的问题,请大家注意有两个重载的std::forward:一个是左值,另一个是右值.
事实上,MyForward给出的实现更像是std::move:它将左值转换为右值(不同之处在于移动也接受rvalues).