Why is `const T&` not sure to be const?

前端 未结 2 1567
离开以前
离开以前 2020-12-24 05:10
template
void f(T a, const T& b)
{
    ++a; // ok
    ++b; // also ok!
}

template
void g(T n)
{
    f(n, n);
}

int         


        
相关标签:
2条回答
  • 2020-12-24 05:30

    Welcome to const and reference collapsing. When you have const T&, the reference gets applied to T, and so does the const. You call g like

    g<int&>(n);
    

    so you have specified that T is a int&. When we apply a reference to an lvalue reference, the two references collapse to a single one, so int& & becomes just int&. Then we get to the rule from [dcl.ref]/1, which states that if you apply const to a reference it is discarded, so int& const just becomes int& (note that you can't actually declare int& const, it has to come from a typedef or template). That means for

    g<int&>(n);
    

    you are actually calling

    void f(int& a, int& b)
    

    and you are not actually modifying a constant.


    Had you called g as

    g<int>(n);
    // or just
    g(n);
    

    then T would be int, and f would have been stamped out as

    void f(int a, const int& b)
    

    Since T isn't a reference anymore, the const and the & get applied to it, and you would have received a compiler error for trying to modify a constant variable.

    0 讨论(0)
  • 2020-12-24 05:32

    I know that there is already an accepted answer which is correct but just to add to it a little bit, even outside the realm of templates and just in function declarations in general...

    ( const T& ) 
    

    is not the same as

    ( const T )
    

    In your example which matches the first, you have a const reference. If you truly want a const value that is not modifiable remove the reference as in the second example.

    0 讨论(0)
提交回复
热议问题