This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 116a. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.
2024-12-19
[Voted into the WP at the July, 2017 meeting.]
It is not clear whether the following is well-formed or not:
template<typename T> int arr[sizeof(T)] = {}; template int arr<int>[];
Are we supposed to instantiate the specialization and treat the explicit instantiation declaration as if it were a redeclaration (in which case the omitted array bound would presumably be OK), or is the type of the explicit instantiation declaration required to exactly match the type that the instantiated specialization has (in which case the omitted bound would presumably not be OK)? Or something else?
(See also issue 1728.)
Proposed resolution (May, 2017):
Change 13.9.3 [temp.explicit] paragraph 3 as follows:
If the explicit instantiation is for a class or member class, the elaborated-type-specifier in the declaration shall include a simple-template-id; otherwise, the declaration shall be a simple-declaration whose init-declarator-list comprises a single init-declarator that does not have an initializer. If the explicit instantiation is for a function or member function, the unqualified-id in thedeclarationdeclarator shall be either a template-id or, where all template arguments can be deduced, a template-name or operator-function-id. [Note: The declaration may declare a qualified-id, in which case the unqualified-id of the qualified-id must be a template-id. —end note] If the explicit instantiation is for a member function, a member class or a static data member of a class template specialization, the name of the class template specialization in the qualified-id for the member name shall be a simple-template-id. If the explicit instantiation is for a variable template specialization, the unqualified-id in thedeclarationdeclarator shall be a simple-template-id. An explicit instantiation shall appear in an enclosing namespace of its template. If the name declared in the explicit instantiation is an unqualified name, the explicit instantiation shall appear in the namespace where its template is declared or, if that namespace is inline (9.8.2 [namespace.def]), any namespace from its enclosing namespace set. [Note:...
Add the following as a new paragraph following 13.9.3 [temp.explicit] paragraph 4:
The declaration in an explicit-instantiation and the declaration produced by the corresponding substitution into the templated function, variable, or class are two declarations of the same entity. [Note: These declarations are required to have matching types as specified in 6.6 [basic.link], except as specified in 14.5 [except.spec]. [Example:
template<typename T> T var = {}; template float var<float>; // OK, instantiated variable has type float template int var<int[16]>[]; // OK, absence of major array bound is permitted template int *var<int>; // error: instantiated variable has type int template<typename T> auto av = T(); template int av<int>; // OK, variable with type int can be redeclared with type auto template<typename T> auto f() {} template void f<int>(); // error: function with deduced return type redeclared with non-deduced return type (9.2.9.7 [dcl.spec.auto])—end example] —end note] Despite its syntactic form, the declaration in an explicit-instantiation for a variable is not itself a definition and does not conflict with the definition instantiated by an explicit instantiation definition for that variable.
Change 13.9.3 [temp.explicit] paragraph 10 as follows:
Except for inline functions and variables, declarations with types deduced from their initializer or return value (9.2.9.7 [dcl.spec.auto]), const variables of literal types, variables of reference types, and class template specializations, explicit instantiation declarations have the effect of suppressing the implicit instantiation of the definition of the entity to which they refer. [Note:...
This resolution also resolves issue 1728.