I was looking through the documentation of SFINAE and there was this template declaration:
template<typename SomeType>
struct inner_type { typedef typename SomeType::type type; };
template <
class T,
class = typename T::type, // SFINAE failure if T has no member type
class U = typename inner_type<T>::type // hard error if T has no member type
// (guaranteed to not occur as of C++14)
> void foo(int) {}
Specifically, I'm asking about class = typename T::type
. What's the point of declaring an unnamed class?
Because of the comment I thought that this will result in a compiler error when T
doesn't have a member type
, but that isn't the case, as foo<int, int, int>(0);
compiles fine.
On the other hand
template<class T, typename = std::enable_if_t<std::is_unsigned<T>::value>>
void foo(T t) {}
doesn't compile if T
is signed, and compiles if T
is unsigned.
What am I missing here?
foo<int, int, int>(0);
compiles fine.
Because you specify the 2nd template argument, then the default template argument (i.e. typename T::type
) won't be used, then won't trigger compile error.
If you just write foo<int>(0);
to make the default template argument to be used, compile will fail.
And it's same for your 2nd sample too.
What's the point of declaring an unnamed class?
Because the template parameter won't be used for the template implementation.