Inexplicable behaviour of the function accepting a universal reference and returning a const reference

  • A+
Category:Languages

I have always thought that the following function, which accepts a universal reference, must return a const-reference.

template <typename T> const T& Const(T&& val) {     return val; } 

However, the following code compiles successfully with VS C++ and gcc:

int x = 5; Const(x) = 6; 

The value of the variable x is equal to 6 after the run. Thus, the Const function returns a non-const reference.

To obtain a compiler error, the function Const must be modified either to accept a conventional l-value reference or to be declared as returning const std::remove_reference_t<T>&.

Why is that? What rule did I miss? Thanks in advance!


an universal reference

No, they're called "forwarding references". The term "universal reference" is deprecated.


Why is that?

When you invoke Const(x), x is an lvalue, therefore T is deduced as int&. Your return type then becomes:

  • const T & = T const & -> int & const & -> int &

int & const & is a reference to a const reference to an int which is the same as int&. (In this case the const applies to int&, not just int, as T = int&).

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: