Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c++

c++11

c++14

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!

like image 251
Alex Avatar asked Apr 26 '18 09:04

Alex


1 Answers

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&).

like image 91
Vittorio Romeo Avatar answered Oct 22 '22 12:10

Vittorio Romeo