Mr.C64
Mr.C64

Reputation: 42924

Const arguments binding to non-const references in C++ templates

Consider something like:

template <typename T>
void f(T& x) 
{
    ....       
}

Why does something like const int binds to f(T&)?

This seems to me kind of a violation of const-correctness. In fact, if f() takes a non-const T& reference, then it's very likely that f() will modify its argument (else, f() would have been defined as void f(const T&)).

In code like this:

template <typename T>
inline void f(T& x) 
{
    x = 0;
}

int main() 
{
    int n = 2;
    f(n);

    const int cn = 10;
    f(cn);
}

the compiler tries to call f() with T = const int, then of course there is an error message because of the x = 0; assignment inside f()'s body.
This is the error message from GCC:

test.cpp: In instantiation of 'void f(T&) [with T = const int]':
test.cpp:13:9:   required from here
test.cpp:4:7: error: assignment of read-only reference 'x'
     x = 0;
       ^

But why does the compiler try to bind a const argument with a function template which takes a non-const parameter?

What's the rationale behind this C++ template rule?

Upvotes: 3

Views: 1259

Answers (3)

Jarod42
Jarod42

Reputation: 217135

T binds to const int.

To avoid that, you may use SFINAE:

template<typename T>
typename std::enable_if<!std::is_const<T>::value, void>::type
f(T& arg) {}

or deleted function:

template <typename T> void f(T& arg) {}
template <typename T> void f(const T&) = delete;

Upvotes: 8

Alex Chi
Alex Chi

Reputation: 736

const int cn = 10;

That means 'cn' is const, you can't change it in anyway, anywhere and anytime.

More:

const int cia = 10;
int ia = 10;

The type of cia is different with ia. So T will be const int, not int.

typedef const int      cint;
cint cia = 10;
int ia = 10;

T will be used as cint, not int.

Upvotes: 0

Cheers and hth. - Alf
Cheers and hth. - Alf

Reputation: 145239

You can use std::enable_if plus e.g. std::is_const to avoid that T binds to a const type.


Re …

“What's the rationale behind this C++ template rule?”

it can possibly be found in Bjarne's design-and-evolution book, but about the most common rationale is that the rules have been chosen for simplicity and uniformity, and so it appears to be also here: treating some types in special ways would introduce needless complexity.

Upvotes: 3

Related Questions