lundi 1 mai 2023

Understanding template type deduction Case 1 in Scott Meyer's Effective Modern C++

In his book Effective Modern C++, section Item 1: Understand template type deduction, Scott Meyers has said the following while discussing Case 1: ParamType is a Reference or Pointer, but not a Universal Reference

These examples all show lvalue reference parameters, but type deduction works exactly the same way for rvalue reference parameters. Of course, only rvalue arguments may be passed to rvalue reference parameters, but that restriction has nothing to do with type deduction.

The lvalue reference examples given in the section before the quoted paragraph are as follows.

If this is our template,

template<typename T>
void f(T& param); // param is a reference

and we have these variable declarations,

int x = 27;          // x is an int
const int cx = x;    // cx is a const int
const int& rx = x;   // rx is a reference to x as a const int

the deduced types for param and T in various calls are as follows:

f(x);  // T is int, param's type is int&
f(cx); // T is const int, param's type is const int&
f(rx); // T is const int, param's type is const int&

The Question: For me, the paragraph quoted above, is a bit confusing for the following reason.

If I try to workout myself, the Case 1 example that deals with rvalue references, how should it look? May be like the following?

template<typename T>
void f(T&& param); // param is an rvalue reference

But isn't this case the same as Case 2: ParamType is a Universal Reference?

How can an rvalue reference be shown in Case 1 without it automatically becoming a Universal/Forwarding reference, since this is in a type deduced context?

One way to understand this is may be to map it to Case 2 sub case 2, where the initializing expression is an rvalue. In that case it is specified to work just as Case 1. So may be this is a loop back from Case 2 to Case 1.

Aucun commentaire:

Enregistrer un commentaire