An argument to this function will bind to an rvalue reference:
void f(int && i);
However, an argument to this function will bind to either an rvalue or an lvalue reference:
template <typename T>
void f(T && t);
I've often heard this referred to as a universal reference.
I've also heard it been called a forwarding reference.
Do they mean the same thing?
Is it only a forwarding reference if the function body calls std::forward
?
Unfortunately, it's confusing, but they are nothing more than two names for the same thing.
Universal reference was proposed (I guess) by Meyers far ago (see here as an example).
Forwarding reference is picked up directly from the standardese. That's all.
Universal reference was a term Scott Meyers coined to describe the concept of taking an rvalue reference to a cv-unqualified template parameter, which can then be deduced as either a value or an lvalue reference.
At the time the C++ standard didn't have a special term for this, which was an oversight in C++11 and makes it hard to teach. This oversight was remedied by N4164, which added the following definition to [temp.deduct]:
Hence, the two mean the same thing, and the current C++ standard term is forwarding reference. The paper itself articulates why "forwarding reference" is a better term than "universal reference."
Nope, what you do with a forwarding reference is irrelevant to the name. The concept forwarding reference simply refers to how the type
T
is deduced in:It does not need to be subsequently forwarded .