Search code examples
c++templatestype-deduction

Why type deduced for T is const int in void func(T const &t)


I am reading about type deduction in templates, and here is a question that bothers me

template<typename T>
void funt(T const &t);
int x = 10;
func(x);

T will be deduced to be const int, and the type of t will be int const & I understand the reasons for why t has to be int const &, so that xpassed to the function would remain the same, because function accepts const T&. But I don't see the reason why T has to be also const. Seems to me that deducing T to be int would not break anything within this piece of code? Like in another example:

template<typename T>
void funt(T const &t);
int const x = 10;
func(x);

Here T is deduced to just int, and const of x is omitted

Or am I missing something here?


Solution

  • The type deduction rules are not very straightforward. But as a general rule of thumb, there are 3 main type-deduction cases:

    1. f(/*const volatile*/ T& arg) - In this instance, the compiler performs something similar to "pattern matching" on the argument to deduce the type T. In your second case, it perfectly matches the type of your argument, i.e. int const, with T const, hence T is deduced as int. In case the argument lacks CV-qualifiers, like in your first example, then the compiler does not consider them in the pattern matching. So, when you pass e.g. an int x to f(const T& param), then const is being discarded during the pattern matching and T is deduced as int, hence f being instantiated to f(const int&).
    2. f(/*const volatile*/ T arg) - The cv-ness (const/volatile) and the references-ness of the argument is ignored. So if you have something like const int& x = otherx; and pass x to template<class T> void f(T param), then T is deduced as int.
    3. f(T&& arg) - T is deduced as either a lvalue reference (like int&) or a rvalue (like int), depending whether arg is a lvalue or a rvalue, respectively. This case is a bit more complicated, and I advise to read more about forwarding references and reference collapsing rules to understand what's going on.

    Scott Meyers discusses template type deduction in Chapter 1 of Effective Modern C++ book in great detail. That chapter is actually free online, see https://www.safaribooksonline.com/library/view/effective-modern-c/9781491908419/ch01.html.