Here is how the function template could be used: #include <iostream> int main() { // This will call max<int> by implicit argument deduction. std::cout << max(3, 7) << '\n'; // This will call max<double> by implicit argument deduction. std::cout << max(3.0, 7.0) << '\n'; // We need to explicitly specify the type of the arguments; // although std::type_identity could solve this problem... std::cout << max<double>(3, 7.0) << '\n'; } In the first two cases, the template argument T is automatically deduced by the compiler to be int and double, respectively. In the third case automatic deduction of max(3, 7.0) would fail because the type of the parameters must in general match the template arguments exactly. Therefore, we explicitly instantiate the double version with max<double>(). This function template can be instantiated with any copy-constructible type for which the expression y > x is valid. For user-defined types, this implies that the greater-than operator (>) must be overloaded in the type. Class templates A class template provides a specification for generating classes based on parameters. Class templates are generally used to implement containers. A class template is instantiated by passing a given set of types to it as template arguments. The C++ Standard Library contains many class templates, in particular the containers adapted from the Standard Template Library, such as vector. Variable templates In C++14, templates can be also used for variables, as in the following example: template<typename T> constexpr T pi = T{3.141592653589793238462643383L}; // (Almost) from std::numbers::pi Non-type template parameters Although templating on types, as in the examples above, is the most common form of templating in C++, it is also possible to template on values. Thus, for example, a class declared with template <int K> class MyClass; can be instantiated with a specific int. As a real-world example, the standard library fixed-size array type std::array is templated on both a type (representing the type of object that the array holds) and a number which is of type std::size_t (representing the number of elements the array holds). std::array can be declared as follows: template<class T, size_t N> struct array; and an array of six chars might be declared: array<char, 6> myArray; Template specialization When a function or class is instantiated from a template, a specialization of that template is created by the compiler for the set of arguments used, and the specialization is referred to as being a generated specialization. Explicit