I saw the usage of something like
#include
#include
using namespace std;
template
void Foo(FN&&a
The rules for deduction of T&& are tricky.
They where designed to make a deduced T&& a "forwarding reference" (or "universal reference").
First, reference collapsing. Suppose you have an unknown type X. For now X is not deduced.
Then if we examine variables of the following type:
typedef X x0;
typedef X& x1;
typedef X const& x2;
typedef X&& x3;
and we set X to be one of int, int&, int const& and int&&, we get:
X is ---> int int& int const& int&&
X int int& int const& int&&
X& int& int& int const& int&
X const& int const& int& int const& int&
X&& int&& int& int const& int&&
live example.
The next bit comes with the deduction rules. If you pass X& to T&& in a deduced context, T is deduced to be X&. This causes T&& to become X& by the above reference collapsing rules. Similar things happen for X const&.
If you pass X&& to T&&, it deduces T to be X. T&& becomes X&& as well.
Between the two of them, in a deduced context, template<class T> void foo(T&&t) is a universal reference (well, now called a forwarding reference).
You can recover the r/l value category of t with std::forward<T>(t), hence the name forwarding reference.
This allows one template to process both l and r values, and use std::forward and similar machinery to behave slightly differently, if you want.
Only processing rvalues requires extra work: you have to use SFINAE or another overload (possibly with =delete). Only processing lvalues is easy (just deduce with T&).