Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is const template parameter not a universal/forwarding reference

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?

like image 528
Jash Jain Avatar asked Dec 08 '22 10:12

Jash Jain


1 Answers

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

like image 83
eerorika Avatar answered May 19 '23 19:05

eerorika