C++ always had support for template argument deduction when calling function templates. For example, suppose you have the following function template:
template<typename T>
void MyFunction(const T& data) { /* ... */}
It’s a function template with one template parameter. When you call this function, you do not have to specify the type of the template parameter explicitly. C++ automatically deduces the type T based on the arguments passed to the function. For example:
MyFunction(5);
MyFunction("Test");
If you really want to specify the template type explicitly you do this as follows:
MyFunction<int>(5);
MyFunction<std::string>("Test");
Up to C++17, this deduction only worked for function templates. C++17 adds support for template argument deduction for constructors of class templates.
For example, before template argument deduction for constructors, when you instantiate any Standard Library container you have to specify the type of the elements you want to store in the container:
std::vector<int> ints = { 11,22,33 };
With C++17’s template argument deduction for constructors, you can omit the explicit specification of the type. Of course, this only works when you instantiate the container and immediately initialize it with initial elements, otherwise the compiler has no data from which it can deduce any types. So, the above example can be written in C++17 as follows:
std::vector ints = { 11,22,33 };
This seemingly little feature has quite an impact. Because of the lack of this feature in previous versions of C++, the Standard Library included helper function templates. For example, a std::pair<int, std::string> can be constructed in the following two ways (pre-C++17):
std::pair<int, std::string> myPair1{ 11, "Eleven" };
auto myPair2 = std::make_pair(12, "Twelve");
Either you directly use the std::pair class and explicitly specify the template parameters, or, you use the specially-introduced std::make_pair() function template that can do the template argument deduction.
With C++17’s new deduction rules, you can forget about the helper function templates, and simply write the following:
std::pair myPair3{ 13, "Thirteen" };
Similarly for other helper function templates that were introduced earlier like std::make_move_iterator() to make a std::move_iterator(), and so on.
If you want to add support for template argument deduction to your own classes, then you will have to write your own so-called deduction guides, but that’s for a future post.