template<typename T> void f(T a, const T& b) { ++a; // ok ++b; // also ok! } template<typename T> void g(T n) { f<T>(n, n); } int main() { int n{}; g<int&>(n); }
Please note: b
is of const T&
and ++b
is ok!
Why is const T&
not sure to be const?
const T* would only forbid you to modify anything the pointer points to, but it allows you (within the bounds of the language) to inspect the value at *(foo+1) and *(foo-1) . Use this form when you're passing pointers to immutable arrays (such as a C string you're only supposed to read).
const T is passed by value (copy is needed), which may be too much for a class while should be ok for built-in types. T& is passed by reference, which could be modified in the function while const T& can't, so it depends on what you need to do. Follow this answer to receive notifications.
The const keyword specifies that a variable's value is constant and tells the compiler to prevent the programmer from modifying it. In C, constant values default to external linkage, so they can appear only in source files.
The purpose of const is to announce objects that may be placed in read-only memory, and perhaps to increase opportunities for optimization.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With