C ++ 11完美的转发和参考折叠
考虑以下代码:
template<typename T>
void foo(T&& param){ //In this case && is called universal reference
std:string tmp = std::forward<string>(param);
}
我的问题是,是否可以推断出通用引用类型,为什么我仍然需要向前调用?
为什么即使不推定t的类型,也不会调用tmp的正确c'tor.
My question is if universal reference type can be deduced why do I still need to call forward ?
Why without forwarding tmp's correct c'tor won't be called even if T's type was deduced.
我的第二个问题是关于参考折叠规则:
My second question is about reference collapsing rules:
-
A& &&
变为A&
-
A&& &&
变为A&&
-
A& &&
becomesA&
-
A&& &&
becomesA&&
因此,根据此规则并考虑通用参考,为什么std :: forward签名不能如下所示:
so according this rules and taking in account universal reference why std::forward signature can't be as follows:
template<class T>
T&& forward(T&& arg){
return static_cast<T&&>(arg);
}
根据上面的规则,如果T
的类型是右值引用,它将折叠为右值引用;如果T的类型是左值引用,它将折叠为左值引用.
那么为什么std::forward
有两个不同的签名,一个用于左值引用,一个用于右值引用,我是否遗漏了一些东西?
According to the rules from above if T
's type is rvalue reference it will collapse to rvalue reference , if T's type is lvalue reference it will collapse to lvalue reference.
So why std::forward
have two different signatures one for lvalue reference and one for rvalue reference am I missing something ?
我的问题是,是否可以推断出通用引用类型,为什么我仍然需要进行前转?
My question is if universal reference type can be deduced why do I still need to call forward ?
因为为参数param
命名后它就是一个左值,即使该函数是用右值调用的,因此除非您使用forward<T>
,否则不会将其作为右值转发>
Because as soon as you give a name to the parameter param
it is an lvalue, even if the function was called with an rvalue, so it wouldn't be forwarded as an rvalue unless you use forward<T>
即使不推定T的类型,为什么不转发tmp的正确c'tor也不会被调用.
Why without forwarding tmp's correct c'tor won't be called even if T's type was deduced.
因为param
是左值.要还原传递给foo
的参数的值类别,您需要将其强制转换回string&
或string&&
,这意味着您需要知道推导为T
的类型,并使用forward
进行操作.演员.
Because param
is an lvalue. To restore the value category of the argument passed to foo
you need to cast it back to string&
or string&&
which means you need to know the type T
was deduced as, and use forward
to do the cast.
那么为什么
std::forward
有两个不同的签名,一个用于左值引用,一个用于右值引用,我是否缺少某些东西?
So why
std::forward
have two different signatures one for lvalue reference and one for rvalue reference am I missing something ?
它已由 http://更改. www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3143.html
http ://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3143.html 和建议版本的问题是,如果您说forward<string>
,则不会推导参数T
,因此它不能用作转发引用,这意味着T&&
不能绑定到左值,并且它必须能够绑定到左值以使forward<string>(param)
起作用,因为param
是在那里的左值.
The problem with your suggested version is that if you say forward<string>
then the parameter T
is not deduced so doesn't function as a forwarding reference, which means that T&&
can't bind to an lvalue, and it needs to be able to bind to an lvalue in order for forward<string>(param)
to work, because param
is an lvalue there.