#for example:
#1:
template <typename T>
void func(T &) {}
int a;
const int b;
func(a); // T -> int
func(b); // T -> const int
func(5); // wrong. 5 is a right value
#2:
template <typename T>
void func(const T &) {}
int a;
const int b;
func(a); // T -> int
func(b); // T -> int
func(5); // T -> int
#3
template <typename T>
void func(T &&) {}
func(5); // T -> int
My question is:
why the 1'st code doesn't work,Why this is related to left/right value;
why T
in the 3'rd is not const int
It all comes down to the properties of expressions. 5
is an expression. It has a type and a value category. The type of 5
is int
, not const int
but just plain int
. And it's a prvalue (that's the value category).
So when deducing T&
against a 5
, the type can only be deduced as int
. Which means the synthesized function accepts a int&
, which cannot bind to an rvalue.
When deducing T const&
, the type T
may still only be deduced as int
under the appropriate provisions in template argument deduction. But now the synthesized function accepts a int const&
, and that may bind to an rvalue just fine.