作用:
用于模板的代理函数中参数转发,而能够保持参数的实际类型
例子:
#include <iostream>
#include <functional>
void add(int& a, int&& b, int c, int *d) {
std::cout << a << std::endl;
std::cout << b << std::endl;
std::cout << c << std::endl;
std::cout << *d << std::endl;
}
void add_proxy(int &a, int &&b, int c, int *d) {
add(a, std::move(b), c, d);
}
template<typename fun, typename A, typename B, typename C, typename D>
void proxy_template(fun f, A&& a, B&& b, C&& c, D&& d) {
f(std::forward<A>(a), std::forward<B>(b), std::forward<C>(c), std::forward<D>(d));
}
int main() {
int a = 1;
add_proxy(a, 2, 3, &a);
proxy_template(add, a, 2, 3, &a);
return 0;
}
add_proxy为明确类型的手动代理调用
proxy_template为模版类型的4参数方法代理调用,其无论你传递的参数为什么类型,均可以按照其实际的类型进行转发
std::forward源码:
template<typename _Tp>
constexpr _Tp&&
forward(typename std::remove_reference<_Tp>::type& __t) noexcept
{ return static_cast<_Tp&&>(__t); }
只列了一种forward情况,另一种为::type&& __t,这种为传递给forward为右值的情况,这里暂时用不上说明:
A&& a,传递实参int a,推导模板参数a为int& && a(引用折叠)->int& a, 所以A=int&,a=int&
std::forward<A>(a)->std::forward<int&>(int&), std::remove_reference<int&>::type->int,所以匹配上面的std::forward源码,
std::remove_reference<int&>::type&->int&
所以最终代码为:
constexpr int& &&forward(std::remove_reference<int&>::type& __t) noexcept {return static_cast<int& &&>(__t):}
constexpr int& forward(std::remove_reference<int&>::type& __t) noexcept {return static_cast<int&>(__t);}
传递给模板的是左值,那么传递下去的还是左值
B&& b,传递3,推导模版参数b为int&& b, 所以B=int,b=int&&
std::forward<B>(b)->std::forward<int>(int&)(虽然b=int&&,虽然称为右值引用,但是只是表明他是一种有能力访问临时变量的引用,后续使用的时候,其本身是作为左值使用),
std::remove_reference<int>::type->int,所以匹配上面的std::forward源码,
std::remove_reference<int>::type&->int&
最终代码为:
constexpr int&& forward(std::remove_reference<int>::type& __t) noexcept { return static_cast<int&&>(__t);}
即传递给模板的是右值,那么传递下去的还是右值
C和B一致
D实际传递为int*,如果把int*整个当作一个左值来看,那么其与A是一致的