I came across this example when looking at std::enable_if:
template<class T,
typename = std::enable_if_t<std::is_array<T>::value> >
void destroy(T* t)
{
for(std::size_t i = 0; i < std::extent<T>::value; ++i) {
destroy((*t)[i]);
}
}
In template argument lists, you can put untemplated classes/structs. So the above code is still possible when we remove the typename =. What does the typename = in this code mean and do?
>Solution :
The typename on the 2nd template argument indicates the argument is a type rather than a constant value.
The argument has no name specified, but the = indicates it has a default type if the caller doesn’t specify one. That type is the result of std::enable_if<...>::type.
The 1st template argument of std::enable_if takes in a boolean constant, and its 2nd template argument (which is optional and is void by default) specifies the type of the std::enable_if<...>::type member when the boolean is true, otherwise the std::enable_if<...>::type member is undefined if the boolean is false. In this case, that boolean is the result of std::is_array<T>::value.
So, if T is an array type, the template resolves to:
template<class T, typename _ = void>
void destroy(T* t)
{
...
}
And if T is not an array type, the template resolves to:
template<class T, typename _ = [undefined] >
void destroy(T* t)
{
...
}
And thus is disabled since the template is invalid.