error: cannot bind non-const lvalue reference of type ‘T&’ to an rvalue of type ‘T’

如果一个参数是以非 const 引用传入,c++ 编译器就有理由认为程序员会在函数中修改这个值,并且这个被修改的引用在函数返回后要发挥作用。

但如果你 把一个临时变量当作非 const 引用参数传进来,由于临时变量的特殊性,程序员并不能操作临时变量,而且临时变量随时可能被释放掉。

所以,修改一个临时变量是毫无意义的。据此,c++ 编译器加入了临时变量不能作为非 const 引用的这个语义限制。

c++ 中临时变量是右值类型,不能取引用,只能在当前行使用,不能作为非 const 的引用参数
std::move() 返回的也是一个右值
对于临时变量或字面量的右值引用可以使用 cosnt &&& 类型的参数接收

一般来说,右值的地址不能通过解引用来获得,因为它们是字面量,或者因为它们本质上是临时的(例如由函数或显式构造函数调用返回的值)。通过将一个对象传递给这个函数,可以获得一个引用它的右值。

class T{
public:
    T(int v){
        a = v;
    }
    T operator+(T &t){
        T temp = this->a + t.a;
        return temp;
    }
    void printT(T &t){
        cout << "a = " << t.a << endl;
    }
    // 方式一
    void printT(const T &t){
        cout << "a = " << t.a << endl;
    }
    // 方式二 C++11 以后添加的右值引用新特性
    void printT(T &&t){
        cout << "a = " << t.a << endl;
    }
private:
    int a;
};
int main()
{
    T t0(0), t1(1), t2(2);
    t0.printT(t1 + t2);     // t1 + t2 返回临时变量 右值

    return 0;
}

输出:

main.cpp:29:18: error: cannot bind non-const lvalue reference of type ‘T&’ to an rvalue of type ‘T’
   29 |     t0.printT(t1 + t2);
      |               ~~~^~~~
main.cpp:20:20: note:   initializing argument 1 of ‘void T::printT(T&)’
   20 |     void printT(T &t){
      |                 ~~~^