We have seen in class templates that we used explicit type for template instantiation for example,
template <typename T, typename U>struct Collection{ T a; U b;};Collection<int, double> c {1, 2.1};
Compiler creates the concrete definition from the template using int and double as template types arguments. However, in C++ 17 onwards, there is a feature called Class template argument deduction (CTAD) that allows us to omit the explicit types and let compiler deduce types from initializer and instantiate the correct template.
For example, consider std::pair (defined in header file <utility>) type which is similar to Collection but stores a pair of data value of any type. We can create pair as shown below,
std::pair<int, int> p{1, 2};// orstd::pair p{1, 2}; // works with C++17 onwards
For second case, compiler does the template type deductions from the initializer list and sees both are ints, so instantiate std::pixel<int,int>.
Does it work for Collection?
Well, we can try following and see if it works or not.
When we compile with C++17, it fails and gives following compilation error on my machine.
ctad.cpp: In function 'int main(int, const char**)':
ctad.cpp:30:22: error: class template argument deduction failed:
30 | Collection c{1, 2};
| ^
ctad.cpp:30:22: error: no matching function for call to 'Collection(int, int)'
ctad.cpp:30:22: note: there are 2 candidates
ctad.cpp:6:8: note: candidate 1: 'template<class T, class U> Collection() -> Collection<T, U>'
6 | struct Collection
| ^~~~~~~~~~
ctad.cpp:6:8: note: candidate expects 0 arguments, 2 provided
ctad.cpp:6:8: note: candidate 2: 'template<class T, class U> Collection(Collection<T, U>) -> Collection<T, U>'
ctad.cpp:6:8: note: candidate expects 1 argument, 2 provided
We would see that compiler is trying to look a match for Collection(int, int) but it could not find it. So, we need to tell the compiler that when such case comes, use the provided rule. For example,
It does not work because CTAD works for deductions for template argument type deductions from the initialization list. It does not work with function parameters. So, this function needs to be used with function template as shown below.