Generalized wording for partial specializations

Document number: P2096R2
Date: 2020-08-17
Project: Programming Language C++, Core Working Group
Reply-to: James Touton <>

Table of Contents

  1. Table of Contents
  2. Revision History
  3. Introduction
  4. Wording
  5. Acknowledgments
  6. References

Revision History

Revision 2 - 2020-08-17

Revision 1 - 2020-03-23

Revision 0 - 2020-02-01


This paper is intended to address CWG issue 1711 by generalizing the existing wording for class template partial specializations to allow for partial specializations of variable templates.


All modifications are presented relative to N4849. "[...]" indicates elided content that is to remain unchanged.

Modify §9.9 namespace.udecl paragraph 11:

Partial specializations of class templates are found by looking up the primary class template and then considering all partial specializations of that template. If a using-declaration names a class template, partial specializations introduced after the using-declaration are effectively visible because the primary template is visible (temp.class.spec).

Modify §13.1 temp.pre paragraph 4:

A template-declaration can appear only as a namespace scope or class scope declaration. Its declaration shall not be an export-declaration. In a function template declaration, the last component of the declarator-id shall not be a template-id. That last component may be an identifier, an operator-function-id, a conversion-function-id, or a literal-operator-id. In a class or variable template declaration, if the classdeclared name is a simple-template-id, the declaration declares a class template partial specialization (temp.class.spec).

Modify §13.1 temp.pre paragraph 6:

A template name has linkage ( Specializations (explicit or implicit) of a template that has internal linkage are distinct from all specializations in other translation units. A template, an template explicit specialization (temp.expl.spec), and a class template partial specialization shall not have C linkage. Use of a linkage specification other than "C" or "C++" with any of these constructs is conditionally-supported, with implementation-defined semantics. Template definitions shall obey the one-definition rule (basic.def.odr). Default arguments for function templates and for member functions of class templates are considered definitions for the purpose of template instantiation (temp.decls) and must also obey the one-definition rule.

Modify §13.4.3 temp.arg.template paragraph 1:

A template-argument for a template template-parameter shall be the name of a class template or an alias template, expressed as id-expression. When the template-argument names a class template, oOnly primary class templates are considered when matching the template template argument with the corresponding parameter; partial specializations are not considered even if their parameter lists match that of the template template parameter.

Modify §13.4.3 temp.arg.template paragraph 2:

Any partial specializations (temp.class.spec) associated with the primary class template or primary variable template are considered when a specialization based on the template template-parameter is instantiated. If a specialization is not visible at the point of instantiation, and it would have been selected had it been visible, the program is ill-formed, no diagnostic required. [...]

Modify §13.7 temp.decls paragraph 1:

Note: A template-id, that is, the template-name followed by a template-argument-list shall notcannot be specified in the declaration ofthe declared name of a primary template declaration.
template<class T1, class T2, int I> class A<T1, T2, I> { }; // error
template<class T1, int I> void sort<T1, I>(T1 data[I]); // error
Note: However, this syntax is allowed in class template partial specializations (temp.class.spec). — end note ]

Rename §13.7.5 temp.class.spec:

Class template pPartial specializations

Modify §13.7.5 temp.class.spec paragraph 1:

A primary class template declaration is one in which the class template name of the template is an identifiernot followed by a template-argument-list. A template declaration in which the class template name is a simple-template-id is a partial specialization of the class template named in the simple-template-id, which shall be a class or variable template. A partial specialization of a class 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.class.spec.match). The primary template shall be declared before any partial specializations of that template. A partial specialization shall be declared before the first use of a class template specialization that would make use of the partial specialization as the result of an implicit or explicit instantiation in every translation unit in which such a use occurs; no diagnostic is required.

Modify §13.7.5 temp.class.spec paragraph 2:

Each class template partial specialization is a distinct template and definitions shall be provided for the members of a template partial specialization (temp.class.spec.mfunc).

Modify §13.7.5 temp.class.spec paragraph 4:

A class template partial specialization may be constrained (temp.pretemp.constr). [...]

Modify §13.7.5 temp.class.spec paragraph 5:

The template parameters of a template are specified in the angle bracket enclosed list that immediately follows the keyword template. For partial specializations, the template argument list is explicitly written immediately following the class template name. For primary templates, this list is implicitly described by the template parameter list (temp.dep.type). Specifically, the order of the template arguments is the sequence in which they appear in the template parameter list. The template argument list for the primary template in the example above is <T1, T2, I>.
The template argument list cannot be specified in the primary template declaration. For example,
template<class T1, class T2, int I>
class A<T1, T2, I> { }; // error

Modify §13.7.5 temp.class.spec paragraph 6:

A class template partial specialization may be declared in any scope in which the corresponding primary template may be defined (namespace.memdef, class.mem, temp.mem). [...]

Modify §13.7.5 temp.class.spec paragraph 7:

Partial specialization declarations themselves are not found by name lookup. Rather, when the primary template name is used, any previously-declared partial specializations of the primary template are also considered. One consequence is that a using-declaration which refers to a class template does not restrict the set of partial specializations which may be found through the using-declaration. [...]

Modify §13.7.5 temp.class.spec paragraph 9:

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

Rename § temp.class.spec.match:

Matching of class template partial specializations

Modify § temp.class.spec.match paragraph 1:

When a class template is used in a context that requires an instantiation of the classtemplate, it is necessary to determine whether the instantiation is to be generated using the primary template or one of the partial specializations. This is done by matching the template arguments of the class template specialization with the template argument lists of the partial specializations.

Modify § temp.class.spec.match paragraph 4:

In a type name that refers to a class template specialization, of a class or variable template (e.g., A<int, int, 1>), the argument list shall match the template parameter list of the primary template. The template arguments of a partial specialization are deduced from the arguments of the primary template.

Rename § temp.class.order:

Partial ordering of class templatepartial specializations

Modify § temp.class.order paragraph 1:

For two class template partial specializations, the first is more specialized than the second if, given the following rewrite to two function templates, the first function template is more specialized than the second according to the ordering rules for function templates (temp.func.order): [...]

Rename § temp.class.spec.mfunc:

Members of class template partial specializations

Modify § temp.class.spec.mfunc paragraph 1:

The template parameter list of a member of a class template partial specialization shall match the template parameter list of the class template partial specialization. The template argument list of a member of a class template partial specialization shall match the template argument list of the class template partial specialization. A class template partial specialization is a distinct template. The members of the class template partial specialization are unrelated to the members of the primary template. Class template partial specialization members that are used in a way that requires a definition shall be defined; the definitions of members of the primary template are never used as definitions for members of a class template partial specialization. An explicit specialization of a member of a class template partial specialization is declared in the same way as an explicit specialization of a member of the primary template. [...]

Modify §13.7.8 temp.concept paragraph 5:

A concept is not instantiated (temp.spec). A concept-id (temp.names) is evaluated as an expression. A concept cannot be explicitly instantiated (temp.explicit), explicitly specialized (temp.expl.spec), or partially specialized (temp.class.spec).

Modify § temp.dep.type paragraph 1:

A name refers to the current instantiation if it is

Optional: Rename the following stable names as shown:

Old NameNew Name


Thanks to Daniel Kr├╝gler and Davis Herring for their feedback on an early version of this paper.


  1. CWG issue 1711: