17 Templates [temp]

17.5 Template declarations [temp.decls]

17.5.5 Class template partial specializations [temp.class.spec]

17.5.5.1 Matching of class template partial specializations [temp.class.spec.match]

Когда шаблон класса используется в контексте, который требует создания экземпляра класса, необходимо определить, должно ли создание экземпляра быть сгенерировано с использованием основного шаблона или одной из частичных специализаций. Это делается путем сопоставления аргументов шаблона специализации шаблона класса со списками аргументов шаблона частичных специализаций.

  • Если найдена ровно одна подходящая специализация, экземпляр создается на основе этой специализации.

  • Если найдено более одной подходящей специализации, partial order rules используются для определения, является ли одна из специализаций более специализированной, чем другие. Если ни одна из специализаций не является более специализированной, чем все другие соответствующие специализации, тогда использование шаблона класса неоднозначно и программа плохо сформирована.

  • Если совпадений не найдено, экземпляр создается из основного шаблона.

Частичная специализация соответствует заданному фактическому списку аргументов шаблона, если аргументы шаблона частичной специализации могут быть deduced из фактического списка аргументов шаблона. [Example:

template<class T1, class T2, int I> class A             { };    // #1
template<class T, int I>            class A<T, T*, I>   { };    // #2
template<class T1, class T2, int I> class A<T1*, T2, I> { };    // #3
template<class T>                   class A<int, T*, 5> { };    // #4
template<class T1, class T2, int I> class A<T1, T2*, I> { };    // #5

A<int, int, 1>   a1;            // uses #1
A<int, int*, 1>  a2;            // uses #2, T is int, I is 1
A<int, char*, 5> a3;            // uses #4, T is char
A<int, char*, 1> a4;            // uses #5, T1 is int, T2 is char, I is 1
A<int*, int*, 2> a5;            // ambiguous: matches #3 and #5

end example]

Если аргументы шаблона частичной специализации не могут быть выведены из-за ее структуры template-parameter-list и структуры template-id, программа плохо сформирована. [Example:

template <int I, int J> struct A {};
template <int I> struct A<I+5, I*2> {};     // error

template <int I> struct A<I, I> {};         // OK

template <int I, int J, int K> struct B {};
template <int I> struct B<I, I*2, 2> {};    // OK

end example]

В имени типа, которое относится к специализации шаблона класса, (например, A<int, int, 1>) список аргументов должен соответствовать списку параметров шаблона первичного шаблона. Аргументы шаблона специализации выводятся из аргументов первичного шаблона.