Are there any use cases for std::forward with a prvalue?

前端 未结 3 1164
醉梦人生
醉梦人生 2021-02-01 17:46

The most common usage of std::forward is to, well, perfect forward a forwarding (universal) reference, like

template
void f(T&         


        
3条回答
  •  無奈伤痛
    2021-02-01 18:03

    Ok since @vsoftco asked for concise use case here's a refined version (using his idea of having "my_forward" to actually see wich overload gets called).

    I interpret "use case" by providing a code sample that without prvalue not compile or behave differently (regardless of that would be really usefull or not).

    We have 2 overloads for std::forward

    #include 
    
    template 
    inline T&& my_forward(typename std::remove_reference::type& t) noexcept
    {
        std::cout<<"overload 1"<(t);
    }
    
    template 
    inline T&& my_forward(typename std::remove_reference::type&& t) noexcept
    {
        std::cout<<"overload 2"<::value,
                  "Can not forward an rvalue as an lvalue.");
        return static_cast(t);
    }
    

    And we have 4 possible use cases

    Use case 1

    #include 
    using namespace std;
    
    class Library
    {
        vector b;
    public:
        // &&
        Library( vector&& a):b(std::move(a)){
    
        }
    };
    
    int main() 
    {
        vector v;
        v.push_back(1);
        Library a( my_forward>(v)); // &
        return 0;
    }
    

    Use case 2

    #include 
    using namespace std;
    
    class Library
    {
        vector b;
    public:
        // &&
        Library( vector&& a):b(std::move(a)){
    
        }
    };
    
    int main() 
    {
        vector v;
        v.push_back(1);
        Library a( my_forward>(std::move(v))); //&&
        return 0;
    }
    

    Use case 3

    #include 
    using namespace std;
    
    class Library
    {
        vector b;
    public:
        // &
        Library( vector a):b(a){
    
        }
    };
    
    int main() 
    {
        vector v;
        v.push_back(1);
        Library a( my_forward>(v)); // &
        return 0;
    }
    

    Use case 4

    #include 
    using namespace std;
    
    class Library
    {
        vector b;
    public:
        // &
        Library( vector a):b(a){
    
        }
    };
    
    int main() 
    {
        vector v;
        v.push_back(1);
        Library a( my_forward>(std::move(v))); //&&
        return 0;
    }
    

    Here's a resume

    1. Overload 1 is used, without it you get compilation error
    2. Overload 2 is used, without it you get compilation error
    3. Overload 1 is used, wihtout it you get compilation error
    4. Overload 2 is used, without it you get compilation error

    Note that if we do not use forward

    Library a( std::move(v));
    //and
    Library a( v);
    

    you get:

    1. Compilation error
    2. Compile
    3. Compile
    4. Compile

    As you see, if you use only one of the two forward overloads, you basically cause to not compile 2 out of 4 cases, while if you do not use forward at all you would get to compile only 3 out of 4 cases.

提交回复
热议问题