转自: https://blog.csdn.net/veghlreywg/article/details/88556681

假设我们有一个函数

    class Data
    {
    };
    void func(Data && data)
    {
    }

那么func能接收什么样的参数输入

情形一

    Data data;
    func(data); //[Error] cannot bind 'Data' lvalue to 'Data&&'

data是个左值,不能绑定到右值上

情形二

        Data data;
        Data & d = data;
        func(d); //[Error] cannot bind 'Data' lvalue to 'Data&&'

d同样是个左值

情形三

都说const 引用和 右值引用有相似之处,尝试传递const 引用

    Data data;
    const Data & d = data;
    func(d); // [Error] invalid initialization of reference of type
             // 'Data&&' from expression of type 'const Data'

情形四

传递匿名对象,匿名对象

func(Data()); // OK

情形五

标准做法

       Data data;   
       func(std::move(data));//OK

情形六

move一个左值引用

        Data data;
        Data & p = data;   
        func(std::move(p)); //OK

情形七

直接声明一个右值引用,来做参数传递

        Data p;
        Data && p1 = std::move(p);
        func(p1); // [Error] cannot bind 'Data' lvalue to 'Data&&'

同样的错误,说明p1 还是左值

我们可以通过这个方式验证一下

    void func(Data && data)
    {
    }
    void func_1(Data && data)
    {
        func(data);//[Error] cannot bind 'Data' lvalue to 'Data&&'
    } 
    Data data;
    func_1(std::move(data));

那么明明是个右值为什么,就变成左值了呢,这个时候就轮到 我们的std::forward出场了

    Data p;
    Data && p1 = std::move(p);
    func(std::forward<Data>(p1)); // OK

    void func_1(Data && data)
    {
       func(std::forward<Data>(data));
    } 
    //这就是完美转发的意义所在

情形八

把一个右值参数传递给const 引用类型

    void func(const Data & data)
    {
    }
    void func_1(Data && data)
    {
        func(data);//OK
    } 
    Data data;
    func_1(std::move(data));

标签: C++

添加新评论