#include <iostream>
#include <boost/type_index.hpp>
template<typename _Tp>
constexpr _Tp&&
forward(typename std::remove_reference<_Tp>::type& __t) noexcept // 实参为左值时
{
std::cout <<"forward(&):std::is_same<int, _Tp>():" << std::is_same<int, _Tp>() << std::endl;
std::cout <<"forward(&):std::is_same<int&, _Tp>():" << std::is_same<int&, _Tp>() << std::endl;
std::cout <<"forward(&):std::is_same<int&&, _Tp>():" << std::is_same<int&&, _Tp>() << std::endl;
std::cout << "run _Tp&" << std::endl;
return static_cast<_Tp&&>(__t);
}
template<typename _Tp>
constexpr _Tp&&
forward(typename std::remove_reference<_Tp>::type&& __t) noexcept // 实参为右值时
{
std::cout <<"forward(&&):std::is_same<int, _Tp>():" << std::is_same<int, _Tp>() << std::endl;
std::cout <<"forward(&&):std::is_same<int&&, _Tp>():" << std::is_same<int&&, _Tp>() << std::endl;
std::cout << "run _Tp&&" << std::endl;
// 因为实参为右值,所以模板推断指定类型_Tp不能为左值引用类型,
// 因为如果是左值引用 static_cast<_Tp &&>类型转换就会是static_cast<& &&>就会变成一个左值引用,一个右值变成一个左值引用显然是不对的
static_assert(!std::is_lvalue_reference<_Tp>::value, "template argument"
" substituting _Tp is an lvalue reference type");
return static_cast<_Tp&&>(__t);
}
template<typename T>
void Tprint(T&& t)
{
std::cout << "Tprint:std::is_same<int &, T>():" << std::is_same<int &, T>() << std::endl;
}
template<typename T>
void foo(T&& fparam)
{
forward<T>(fparam);
}
int main()
{
int a = 100;
const int b = 101;
int& lref = a;
int&& rref = std::move(a);
std::cout << "int a: type is " << boost::typeindex::type_id_with_cvr<decltype(a)>().pretty_name() << std::endl;
std::cout << "const int b: type is " << boost::typeindex::type_id_with_cvr<decltype(b)>().pretty_name() << std::endl;
std::cout << "int& lref: type is " << boost::typeindex::type_id_with_cvr<decltype(lref)>().pretty_name() << std::endl;
std::cout << "int&& rref: type is " << boost::typeindex::type_id_with_cvr<decltype(rref)>().pretty_name() << std::endl;
Tprint(rref);
forward<int>(1);
std::cout << "forward<int>(lref): type is " << boost::typeindex::type_id_with_cvr<decltype(forward<int>(lref))>().pretty_name() << std::endl;//这个将左值转化成了右值
std::cout << "forward<int &>(lref): type is " << boost::typeindex::type_id_with_cvr<decltype(forward<int &>(lref))>().pretty_name() << std::endl;
foo(1);
return 0;
}
//编译:g++ prog.cc -Wall -Wextra -I/opt/wandbox/boost-1.83.0-gcc-13.2.0/include -std=c++11
运行结果:
prog.cc: In instantiation of 'void Tprint(T&&) [with T = int&]':
prog.cc:51:11: required from here
prog.cc:28:17: warning: unused parameter 't' [-Wunused-parameter]
28 | void Tprint(T&& t)
| ~~~~^
int a: type is int
const int b: type is int const
int& lref: type is int&
int&& rref: type is int&&
Tprint:std::is_same(int &, T):1
forward(&&):std::is_same<int, _Tp>():1
forward(&&):std::is_same<int&&, _Tp>():0
run _Tp&&
forward(lref): type is int&&
forward(lref): type is int&
forward(&):std::is_same<int, _Tp>():1
forward(&):std::is_same<int&, _Tp>():0
forward(&):std::is_same<int&&, _Tp>():0
run _Tp&
C++11中std::move和std::forward到底干了啥(最后一个例子t为右值引用类型是个左值所以调用的是forward的左值版本不是右值版本,写的完全错了)
浅谈std::move和std::forward原理
https://wandbox.org/permlink/tUy8bm3XKLkoTBiF
 
std::forward完美转发:等您坐沙发呢!