Мне непонятно взаимодействие аргументов шаблона по умолчанию в контексте частичной специализации для выбора наиболее подходящего шаблона. Эти вопросы связаны с кодом, размещенным в этом -data-member">ответ от max66.
Учитывая определения классов A
и B
:
template <int N> struct A { static const int code = N; };
struct B{};
и следующие классы шаблонов:
// primary template
template <typename, typename Enable = bool_constant<true>>
struct cond : public bool_constant<false> {};
// specialization
template <typename T>
struct cond<T, bool_constant<(0 == T::code)>> : public bool_constant<true> {};
1) cond<B>::value
оценивается как false
(т. е. выбирается первичный). Это ясно, так как основной шаблон дает cond<B, bool_constant<true>>
, специализация терпит неудачу, следовательно, основной шаблон является единственным возможным выбором.
2) cond<A<0>>::value
оценивается как true
(т.е. специализация выбрана). Это ясно, так как основной шаблон дает cond<B, bool_constant<true>>
, специализация также дает cond<B, bool_constant<true>>
, поэтому специализация предпочтительнее, поскольку аргумент для второго параметра шаблона задан явно.
3) cond<A<1>>::value
оценивается как false
(т. е. выбирается первичный). Это мне непонятно. Основной шаблон дает cond<B, bool_constant<true>>
, специализация дает cond<B, bool_constant<false>>
. Учитывая, что аргумент для второго параметра шаблона явно указан в специализации, почему он не предпочтителен?
Я предполагаю, что поведение в (3) связано с некоторым взаимодействием между аргументом шаблона по умолчанию основного шаблона и специализацией. В этом ответе Джерри Коффин говорит что-то, что может объяснить такое поведение:
если мы изменим специализацию так, чтобы ее специализация была для типа, отличного от значения по умолчанию, предоставленного базовым шаблоном, то будет выбран базовый шаблон.
Кто-нибудь может уточнить это правило? Спасибо