Std::forward 和模板类型推导
Std::forward and template type deduction
我编写了以下小程序来了解 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&&) 。关于 std::forward 的工作原理,我是完全理解错误还是存在细微错误?或者更糟的是,代码是否应该按照我的预期工作,也许我搞砸了我的编译器实现?
Btw.I正在使用 g++ 7.2
Did I understand something completely wrong about how std::forward works
是的。 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
强制转换为右值引用,而不是像您这样的左值引用预期。
我编写了以下小程序来了解 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&&) 。关于 std::forward 的工作原理,我是完全理解错误还是存在细微错误?或者更糟的是,代码是否应该按照我的预期工作,也许我搞砸了我的编译器实现? Btw.I正在使用 g++ 7.2
Did I understand something completely wrong about how std::forward works
是的。 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
强制转换为右值引用,而不是像您这样的左值引用预期。