[temp.spec.partial.general]

# 13 Templates [[temp]](./#temp)

## 13.7 Template declarations [[temp.decls]](temp.decls#temp.spec.partial.general)

### 13.7.6 Partial specialization [[temp.spec.partial]](temp.spec.partial#general)

#### 13.7.6.1 General [temp.spec.partial.general]

[1](#1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3655)

A partial specialization of a template provides an alternative definition
of the template that is used instead of the primary definition when the
arguments in a specialization match those given in the partial
specialization ([[temp.spec.partial.match]](temp.spec.partial.match "13.7.6.2 Matching of partial specializations"))[.](#1.sentence-1)

A declaration of the primary template shall precede
any partial specialization of
that template[.](#1.sentence-2)

A partial specialization shall be reachable from any use of a template
specialization that would make use of the partial specialization as the result of
an implicit or explicit instantiation; no diagnostic is required[.](#1.sentence-3)

[2](#2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3668)

Two partial specialization declarations declare the same entity
if they are partial specializations of the same template and have equivalent[*template-head*](temp.pre#nt:template-head "13.1 Preamble [temp.pre]")*s* and template argument lists ([[temp.over.link]](temp.over.link "13.7.7.2 Function template overloading"))[.](#2.sentence-1)

Each partial specialization is a distinct template[.](#2.sentence-2)

[3](#3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3674)

[*Example [1](#example-1)*: template<class T1, class T2, int I> class A { };template<class T, int I> class A<T, T*, I> { };template<class T1, class T2, int I> class A<T1*, T2, I> { };template<class T> class A<int, T*, 5> { };template<class T1, class T2, int I> class A<T1, T2*, I> { };

The first declaration declares the primary (unspecialized) class template[.](#3.sentence-1)

The second and subsequent declarations declare partial specializations of
the primary template[.](#3.sentence-2)

â *end example*]

[4](#4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3689)

A partial specialization may be constrained ([[temp.constr]](temp.constr "13.5 Template constraints"))[.](#4.sentence-1)

[*Example [2](#example-2)*: template<typename T> concept C = true;

template<typename T> struct X { };template<typename T> struct X<T*> { }; // #1template<C T> struct X<T> { }; // #2

Both partial specializations are more specialized than the primary template[.](#4.sentence-2)

#1 is more specialized because the deduction of its template arguments
from the template argument list of the class template specialization succeeds,
while the reverse does not[.](#4.sentence-3)

#2 is more specialized because the template arguments are equivalent,
but the partial specialization is more constrained ([[temp.constr.order]](temp.constr.order "13.5.5 Partial ordering by constraints"))[.](#4.sentence-4)

â *end example*]

[5](#5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3707)

The template argument list of a partial specialization is
the [*template-argument-list*](temp.names#nt:template-argument-list "13.3 Names of template specializations [temp.names]") following the name of the template[.](#5.sentence-1)

[6](#6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3711)

A partial specialization may be declared in any
scope in which the corresponding primary template
may be defined ([[dcl.meaning]](dcl.meaning "9.3.4 Meaning of declarators"), [[class.mem]](class.mem "11.4 Class members"), [[temp.mem]](temp.mem "13.7.3 Member templates"))[.](#6.sentence-1)

[*Example [3](#example-3)*: template<class T> struct A {struct C {template<class T2> struct B { }; template<class T2> struct B<T2**> { }; // partial specialization #1};};

// partial specialization of A<T>​::​C​::​B<T2>template<class T> template<class T2>struct A<T>::C::B<T2*> { }; // #2 A<short>::C::B<int*> absip; // uses partial specialization #2 â *end example*]

[7](#7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3732)

Partial specialization declarations do not introduce a name[.](#7.sentence-1)

Instead, when the primary template name is used, any reachable partial
specializations of the primary template are also considered[.](#7.sentence-2)

[*Note [1](#note-1)*:

One consequence is
that a [*using-declaration*](namespace.udecl#nt:using-declaration "9.10 The using declaration [namespace.udecl]") which refers to a class template does not restrict the set of partial specializations
that are found through the [*using-declaration*](namespace.udecl#nt:using-declaration "9.10 The using declaration [namespace.udecl]")[.](#7.sentence-3)

â *end note*]

[*Example [4](#example-4)*: namespace N {template<class T1, class T2> class A { }; // primary template}using N::A; // refers to the primary templatenamespace N {template<class T> class A<T, T*> { }; // partial specialization} A<int,int*> a; // uses the partial specialization, which is found through the using-declaration// which refers to the primary template â *end example*]

[8](#8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3759)

A constant template argument is non-specialized if it is the name of a constant
template parameter[.](#8.sentence-1)

All other constant template arguments are specialized[.](#8.sentence-2)

[9](#9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3764)

Within the argument list of a partial specialization,
the following restrictions apply:

- [(9.1)](#9.1)

  The type of a template parameter corresponding to a specialized constant template
argument shall not be dependent on a parameter of the partial specialization[.](#9.1.sentence-1)
  [*Example [5](#example-5)*: template <class T, T t> struct C {};template <class T> struct C<T, 1>; // errortemplate< int X, int (*array_ptr)[X] > class A {};int array[5];template< int X > class A<X,&array> { }; // error â *end example*]

- [(9.2)](#9.2)

  The partial specialization shall be more specialized than the primary
template ([[temp.spec.partial.order]](temp.spec.partial.order "13.7.6.3 Partial ordering of partial specializations"))[.](#9.2.sentence-1)

- [(9.3)](#9.3)

  The template parameter list of a partial specialization shall not contain default
template argument values[.](#9.3.sentence-1)[114](#footnote-114 "There is no context in which they would be used.")

- [(9.4)](#9.4)

  An argument shall not contain an unexpanded pack[.](#9.4.sentence-1)
  If
an argument is a pack expansion ([[temp.variadic]](temp.variadic "13.7.4 Variadic templates")), it shall be
the last argument in the template argument list[.](#9.4.sentence-2)

[10](#10)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3797)

The usual access checking rules do not apply to non-dependent names
used to specify template arguments of the [*simple-template-id*](temp.names#nt:simple-template-id "13.3 Names of template specializations [temp.names]") of the partial specialization[.](#10.sentence-1)

[*Note [2](#note-2)*:

The template arguments can be private types or
objects that would normally not be accessible[.](#10.sentence-2)

Dependent names cannot be checked when declaring the partial specialization,
but will be checked when substituting into the partial specialization[.](#10.sentence-3)

â *end note*]

[114)](#footnote-114)[114)](#footnoteref-114)

There is no context in which they would be used[.](#footnote-114.sentence-1)
