我编写了以下小程序来了解std :: forward的工作原理。
#include <iostream>
#include <memory>
template<class T>
void foo3(T&& bar){
std::cout<<"foo3&&"<<std::endl;
}
template<class T>
void foo3(T& bar){
std::cout<<"foo3&"<<std::endl;
}
template<class T>
void foo(T&& bar){
std::cout<<"foo&&"<<std::endl;
foo3(std::forward<T>(bar));
}
template<class T>
void foo(T& bar){
std::cout<<"foo&"<<std::endl;
foo3(std::forward<T>(bar));
}
int main(int argc, char * argv []){
int i = 1;
foo(2);
foo(i);
return 0;
}
我希望得到以下结果:
"foo&&"
"foo3&&"
"foo&"
"foo3&"
但是,我得到以下结果,我无法解释:
"foo&&"
"foo3&&"
"foo&"
"foo3&&"
因此,如果用左值调用foo,我希望foo将转发左值并调用foo3的左值版本。然而,一直调用foo3(T&amp;&amp;)。我是否理解std :: forward如何工作还是存在一个微妙的错误?或者更糟糕的是,代码是否应该像我预期的那样工作,也许我搞砸了我的编译器实现? 顺便说一下,我正在使用g ++ 7.2
答案 0 :(得分:4)
我是否理解std :: forward如何工作完全错误
是。 std::forward
用于转发引用,而bar
中的void foo(T&)
则不是。如果你不尊重这一点,你会得到一些奇怪的行为。
要理解为什么你需要了解std::forward
实际上做了什么。这只是演员
static_cast<T&&>(t)
t
是std::forward
的参数。因此,foo
的最终调用如下所示:
std::cout<<"foo&"<<std::endl;
foo3(std::forward<int>(bar));
T
被推导为int
,如果查看演员表,您会看到它将bar
转换为右值引用,而不是像您预期的左值引用。