Sometimes I see syntax like this.
template<typename T,typename = int>
int foo(){
//...
}
what part typename = int mean?
Where it can be used?
foo has two template arguments. The first is called T and the second is unnamed and defaults to int.
In your piece of code alone there is no reason to use the second argument. Unnamed template arguments often come up with SFINAE. An example from cppreference:
// primary template handles non-referenceable types:
template<class T, class = void>
struct reference_traits {
using add_lref = T;
using add_rref = T;
};
// specialization recognizes referenceable types:
template<class T>
struct reference_traits<T, std::void_t<T&>> {
using add_lref = T&;
using add_rref = T&&;
};
template<class T>
using add_lvalue_reference_t = typename reference_traits<T>::add_lref;
template<class T>
using add_rvalue_reference_t = typename reference_traits<T>::add_rref;
The only reason for the primary template to have a second argument is that it can be specialized. When possible the more specialized specialization is instantiatied. If this fails (because T& is not valid) then "substitution failure is not an error" (SFINAE) kicks in and the primary template is instantiated instead.
A simpler example of unnamed argument is when you want a template argument merely as a tag to distinguish different instantiations:
template<typename = int>
struct bar {
// ...
};
Even if the implementation of bar does not depend on the template argument you might want to have bar<double> and bar<std::string> be two distinct types.
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