I am not clear about the interaction of default template arguments in the context of partial specialization, for choosing which is the better matching template. This questions s
template <typename, typename Enable = bool_constant<true>>
struct cond : public bool_constant<false> {};
is identical to
template <typename, typename Enable = bool_constant<true>> struct cond;
template <typename, typename Enable>
struct cond : public bool_constant<false> {};
Later might be clearer to understand the result.
When you write cond<C>
, thanks to default argument, it is equivalent to cond<C, bool_constant<true>>
.
Then we try to match that to "better instantiation".
We have the choice between:
// primary template
template <typename, typename Enable>
struct cond : public bool_constant<false> {};
and partial specialization, which use SFINAE:
// specialization
template <typename T>
struct cond<T, bool_constant<(0 == T::code)>> : public bool_constant<true> {};
If 0 == T::code
is ill formed, specialization is discarded and only primary template is a viable solution, so it is used.
Else if 0 == T::code
evaluates to false
, the specialization doesn't match and primary template is also used.
Note that using cond<C, bool_constant<false>>
would use the specialization in that case.
Else, 0 == T::code
evaluates to true
, and then both primary and specialization are viable, but specialization is more specialized, so it is chosen.