C++11 perfect forwarding and reference collapsing

左心房为你撑大大i 提交于 2019-12-10 11:49:27

问题


Consider this code:

template<typename T>
void foo(T&& param){ //In this case && is called universal reference
    std:string tmp = std::forward<string>(param);
}

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:

  1. A& && becomes A&
  2. A&& && becomes A&&

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);
}

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 ?


回答1:


My question is if universal reference type can be deduced why do I still need to call forward ?

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>

Why without forwarding tmp's correct c'tor won't be called even if T's type was deduced.

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.

So why std::forward have two different signatures one for lvalue reference and one for rvalue reference am I missing something ?

It was changed by http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3143.html

There is lots of background info in http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3143.html and http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2951.html

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.



来源:https://stackoverflow.com/questions/27409383/c11-perfect-forwarding-and-reference-collapsing

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!