I was playing with C++ template type deduction and managed to compile this little program.
template<typename T>
void f(const T& val)
{
val = 1;
}
int main()
{
int i = 0;
f<int&>(i);
}
It compiles on all major compilers but I do not understand why. Why can f assign to val, when val is explicitly marked const? Is it bug in these compilers or is it valid behavior according to the C++ standard?
§8.3.2 [dcl.ref]/p6:
This is known as reference collapsing and is introduced in C++11. In C++03, your code would be ill-formed, but some compilers supported it as an extension.
Note that in
const T &, theconstapplies to the typeT, so whenTisint &, theconstwould apply to the reference type itself (which is meaningless as references are immutable anyway), not the type referred to. This is why the reference collapsing specification ignores any cv-qualifiers onTR.*A template type parameter is a typedef-name, per §14.1 [temp.param]/p3: