刚看到这时,有一个疑问,好像 T && universal reference 已经可以接受所有类型的参数,并且保持原来参数的类型。为什么还要有forward呢。想明白后发现 T && 转发并不完美,在转发右值的时候会出问题, 有如下例子
void foo(int&& foo_arg)
{
}
template<typename T>
void fwd(T&& fwd_arg)
{
foo(fwd_arg);//编译错误,需要forward<T>(fwd_arg)
}
int main(){
fwd(30);
}
当传入字面常量30,模版参数T推导成 int ,模版实例化结果如下
void fwd(int&& fwd_arg) {
foo(fwd_arg);
}
虽然fwd_arg是的类型是右值引用,但fwd_arg本身是左值,当继续给foo传值的时候其实是一个int && 类型的左值。 就会产生编译错误
这个时候就要用,forward了,因为fwd_arg本身是左值,foo的参数是个右值引用,无法绑定到一个左值上。
用forward<T>(fwd_arg)当实参,T推断成int&&,所以返回值是int&& &&,折叠成int&&,可以被绑定到foo参数的右值引用上,就没有错误了
所以,universal reference 转发时并不完美,只完美了一半,当转发目标的的参数是右值引用时,会出现问题。
std::forward 解决当转发目标的的参数是右值引用时的问题。可以保持原始参数的类型,将实参从原来的类型为右值引用的左值,变成了本身就是右值引用
网友评论