Carlos Miguel Colanta
Carlos Miguel Colanta

Reputation: 2823

Passing an lvalue to rvalue template parameter won't allow me to declare const T& var

Just a quick query regarding reference collapsing, and this is my code:

template<typename B>
void funct(B&& b)
{
    const B woi= 10; // ERROR: B is int& , how come it won't let me make const int& var?                     // If B is int(just incase i am wrong), it still won't work
    b = 11;
}


int main(int argc, char** argv) {


    int k =10;  
    funct(k);
    std::cout<<k<<std::endl; //prints 11;

    return 0;
}

I was playing around and doing some testings. How come it won't let me create const int& var wherein B is type int&?

I did another attempt to make sure that it's int& and here's the code:

template<typename B>    //B will be deducated as B& or int&
void funct2(B&& b){     //receives lvalue refence, param will be B& b

const B p = 5;          //ERROR eventhough B is B& or int&
}
int main(int argc, char** argv) {



    //make ref
    int l = 5;
    int & m = l;
    funct2(m);  //passed an lvalue reference


    return 0;
}

Question: how come it won't let me reuse int& as const ?

Edit: I am aware that const int& is mainly used for lvalues but const int & var = 10 totally works fine on main/functions but not with B.

Example:

template<typename B>
void funct(B&& b)
{

const int& p = 10;
//const B woi= 10;  gives me errors

}

Though they are supposed to be the same.

Upvotes: 2

Views: 54

Answers (1)

TartanLlama
TartanLlama

Reputation: 65610

The issue is that adding const to int& means a const reference, not a reference to const, i.e. const B where B is int& is not const int&. A const reference is just the same as a normal reference, so it can't bind to rvalues.

If you want a const int& both when an lvalue or rvalue is passed in, you can do this:

const std::remove_reference_t<B>& woi; //c++14
const typename std::remove_reference<B>::type& woi; //c++11

Upvotes: 3

Related Questions