I've stumbled upon Scott Mayers article on universal references, link.
From what I understood universal reference, that is some type T&&
can mean an rvalue or lvalue type in different contexts.
For example:
template<typename T>
void f(T&& param); // deduced parameter type ⇒ type deduction;
// && ≡ universal reference
In the above example depending on template parameter the T&&
can be either an lvalue or rvalue, that is, it depends on how we call f
int x = 10;
f(x); // T&& is lvalue (reference)
f(10); // T&& is rvalue
However according to Scott, if we apply const
to to above example the type T&&
is always an rvalue:
template<typename T>
void f(const T&& param); // “&&” means rvalue reference
Quote from the article:
Even the simple addition of a const qualifier is enough to disable the interpretation of “&&” as a universal reference:
Question:
Why does const
make an "universal" reference rvalue?
I think this is impossible because following code makes confusion then:
template<typename T>
void f(const T&& param); // “&&” means rvalue reference
int x = 10;
f(x); // T&& is lvalue (reference) // how does 'x' suddenly become an rvalue because of const?
f(10); // T&& is rvalue // OK
x
does not "suddenly become" anything. – Unbeatenconst
affect universal references. as shown in examples above. – Astrakhan(T const &¶m)
'.const
affects universal references in the way the Scott Meyers describes: it disables them. – Gorlinas_const
. – Unbeaten