Когда шаблон класса используется в контексте, который требует создания экземпляра класса, необходимо определить, должно ли создание экземпляра быть сгенерировано с использованием основного шаблона или одной из частичных специализаций. Это делается путем сопоставления аргументов шаблона специализации шаблона класса со списками аргументов шаблона частичных специализаций.
Если найдена ровно одна подходящая специализация, экземпляр создается на основе этой специализации.
Если найдено более одной подходящей специализации, 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 ]