#include
using namespace std;
template
void f(T&&) { cout << \"f(T&&)\" << endl; }
template
Why do primitive and user-defined types act differently when returned as 'const' from a function?
Because const part is removed from primitive types returned from functions. Here's why:
In C++11 from § 5 Expressions [expr] (p. 84):
8
Whenever a glvalue expression appears as an operand of an operator that expects a prvalue for that operand, the lvalue-to-rvalue (4.1), array-to-pointer (4.2), or function-to-pointer (4.3) 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 type int is required. —end note]
And similarly from § 5.2.3 Explicit type conversion (functional notation) [expr.type.conv] (p. 95):
2
The expression T(), where T is a simple-type-specifier or typename-specifier for a non-array complete object type or the (possibly cv-qualified) void type, creates a prvalue of the specified type,which is valueinitialized (8.5; no initialization is done for the void() case). [Note: if T is a non-class type that is cv-qualified, the cv-qualifiers are ignored when determining the type of the resulting prvalue (3.10). —end note]
What that means is that const int prvalue returned by g2() is effectively treated as int.