#include
using namespace std;
template
void f(T&&) { cout << \"f(T&&)\" << endl; }
template
Quotes from the standard,
§8/6 Expressions [expr]
If a prvalue initially has the type “cv T”, where T is a cv-unqualified non-class, non-array type, the type of the expression is adjusted to T prior to any further analysis.
and §8/9 Expressions [expr]
(emphasis mine)
Whenever a glvalue expression appears as an operand of an operator that expects a prvalue for that operand, the lvalue-to-rvalue, array-to-pointer, or function-to-pointer standard conversions are applied to convert the expression to a prvalue. [ Note: Because cv-qualifiers are removed from the type of an expression of non-class type when the expression is converted to a prvalue, an lvalue expression of type
const int
can, for example, be used where a prvalue expression of typeint
is required. — end note ]
So for g2()
, int
is a non-class type, and (the return value of) g2()
is a prvalue expression, then const
qualifier is removed, so the return type is not const int
, but int
. That's why f(T&&)
is called.