Search code examples
c++templatestemplate-argument-deduction

What's the difference between const T & and T & in template deduction


#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


Solution

  • 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.