Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is this a forwarding reference?

Tags:

The distinction between rvalue references and forwarding references was made clear enough in this example by Scott Meyers:

Widget&& var1 = someWidget;     // here, “&&” means rvalue reference (1)  auto&& var2 = var1;             // here, “&&” does not mean rvalue reference (2)  template<typename T> void f(std::vector<T>&& param); // here, “&&” means rvalue reference (3)  template<typename T> void f(T&& param);              // here, “&&”does not mean rvalue reference (4) 

Essentially the distinction happens when we have a deducible context, hence case (3) explicitly states that we have a vector<...>&& whereas the T in case (4) is to be deduced and (after applying reference collapsing rules) categorized in terms of "value category".

But what happens with a bit more complex pattern matching? Take the following case for example :

template <template <class...> class Tuple, class... Ts> void f(Tuple<Ts...>&& arg) {  } 

What does && mean here ?

like image 618
Lorah Attkins Avatar asked Nov 26 '16 13:11

Lorah Attkins


People also ask

What are forwarding references?

I understand that a forwarding reference is "an rvalue reference to a cv-unqualified template parameter", such as in. template <class T> void foo(T&& ); which means the above function can take both l-value and r-value reference.

What is a forwarding universal reference?

A forwarding reference is an rvalue reference to a cv-unqualified template parameter. If P is a forwarding reference and the argument is an lvalue, the type “lvalue reference to A” is used in place of A for type deduction. Hence, the two mean the same thing, and the current C++ standard term is forwarding reference.

What is a reference declaration?

A reference variable declaration is any simple declaration whose declarator has the form. & attr(optional) declarator. (1) && attr(optional) declarator.

What is perfect forwarding?

What is Perfect Forwarding. Perfect forwarding allows a template function that accepts a set of arguments to forward these arguments to another function whilst retaining the lvalue or rvalue nature of the original function arguments.


2 Answers

In your last example, arg is an rvalue reference.

A forwarding reference is an rvalue reference to a cv-unqualified template parameter

and Tuple<Ts...> is not a template parameter.

(Citation from [temp.deduct.call].)

like image 143
Kerrek SB Avatar answered Dec 29 '22 06:12

Kerrek SB


It is a rvalue reference, not a forwarding reference.

The easiest way to be sure is to try to pass an lvalue, if it fails, then it is a rvalue reference, if not, then a forwarding reference:

template<typename... Ts> struct foo {};  //f function definition  int main() {     foo<int, double> bar;     f(bar); // fails! Cannot bind lvalue to rvalue reference     f(foo<int, double>{}); // ok, rvalue is passed } 
like image 45
Rakete1111 Avatar answered Dec 29 '22 04:12

Rakete1111