I am confused with the below template behavior, where it compiles fine with the empty angle brackets (template without parameters) since syntactically, template<> is reserved to mark an explicit template specialization.
template <typename T> void add(T a, T b) { }
int main() {
add<>(10, 3); // compiles fine since both parameters are of same data type
add<>(10, 3.2); // Error: no matching function for call to add(int, double)
}
In the above case is the template parameter really optional?
It's a specialization. template<> means that the specialization itself is not templated- i.e., it is an explicit specialization, not a partial specialization.
Defining a Function Template A function template starts with the keyword template followed by template parameter(s) inside <> which is followed by the function definition. In the above code, T is a template argument that accepts different data types ( int , float , etc.), and typename is a keyword.
Function templates are similar to class templates but define a family of functions. With function templates, you can specify a set of functions that are based on the same code but act on different types or classes.
A template non-type parameter is a template parameter where the type of the parameter is predefined and is substituted for a constexpr value passed in as an argument. A non-type parameter can be any of the following types: An integral type. An enumeration type. A pointer or reference to a class object.
template<>
is reserved to mark an explicit template specialization.
It means various things, depending on context. Here it means "use the default or deduced argument", just as if you simply said add
.
In the first case, both function arguments have the same type, so the template argument can be deduced as int
.
In the second case, they have different types, so the template argument can't be deduced. You'd have to specify what you want, e.g. add<double>
, convert one function argument to match the other, or modify the template to parametrise each type separately.
In the above case is the template parameter really optional?
Yes, if it can be deduced from the argument types.
In the first case, yes because the can be inferred through the standard's rules. In the second, no because they can't - you'd have to write something like:
add<float>(10, 3.2);
You have a single template parameter and two function parameters of different types. Template argument deduction needs to match for both arguments, but if you supply an int and a double, it doesn't work. The reason is that deduced argument have to an exact match and type conversions are not considered.
The syntax
add<double>(10, 3.2);
would explicitly force T
to be equal to double
. In that case, the int
constant 10
is converted to double
.
You could also add another overload
template <typename T, typename U> void add(T a, U b) { }
and possibly constrain that using SFINAE by requiring that is_convertible<T, U>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With