I'm reading about universal references/forwarding references and this link says that:
Here param
is a universal reference:
template<typename T>
void f(T&& param);
But here param
is not a universal reference, it is an rvalue reference:
template<typename T>
void f(const T&& param);
The definition for universal references is given as:
If a variable or parameter is declared to have type T&& for some deduced type T, that variable or parameter is a universal reference.
And I've read that T is a deduced type because of Template argument deduction.
Why is the second case not a universal reference? Does the presence of const T&& param
not follow Template Argument Deduction, for some reason? If so, why?
Foreword: The official term is forwarding reference.
So why is the second case not a universal reference?
Because it is a reference to const. And references to const are not forwarding references.
why?
The whole point of a forwarding reference is that when an rvalue is given as an argument, the parameter will be deduced as reference to non-const rvalue which allows such argument to be moved from when forwarding (while simultaneously allowing lvalues to not be moved from). You cannot move from a reference to const because the argument of the move constructor will be an rvalue reference to non-const which cannot be bound to a reference to const.
The language-lawyer answer is: Because the standard says so:
[temp.deduct.call] A forwarding reference is an rvalue reference to a cv-unqualified template parameter that does not represent a template parameter of a class template ...
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