c++templatesc++20lvalue

Template class method f(const T) don't accept rvalue when T is lvalue reference


In the following codes, I have two versions of class A instantiated, one is bound to int and the other to int&.

The method forward has const in its parameter, so the int& version should have the parameter const int& t.

A rvalue can be used as const T&, however, the compiler complains about binding a non-const lvalue to a rvalue.

I have const in the code, so why isn't it working?

#include <iostream>
using namespace std;

template <typename T>
class A
{
public:
    T forward(const T t)
    {
        return t;
    }
};

int main()
{
    A<int> a;
    A<int&> al;
    int i = 1;
    cout << a.forward(1) << endl;  //ok
    cout << al.forward(i) << endl; //ok
    cout << al.forward(1) << endl;  //error: non-const lvalue reference to type 'int' cannot bind to a temporary of type 'int'
    return 0;
}

The error goes away when I add these codes or replace A<int&> with A<const int&>.

template <typename T>
class A<T&>
{
public:
    T& forward(const T& t)
    {
        return t;
    }
};

But I don't understand why.


Solution

  • References cannot be const-qualified in C++. This means that your attempt to add a top-level const to int& does not work(i.e., ignored).

    This essentially means that the parameter of A<int&>::forward is of type int& which can only bind to an lvalue.