If a template, a member template or a member of a class template is explicitly specialized, a declaration of that specialization shall be reachable from every use of that specialization that would cause an implicit instantiation to take place, in every translation unit in which such a use occurs; no diagnostic is required.
Consider the formal example after the above rule
template<class T> struct A {
enum E : T;
enum class S : T;
};
template<> enum A<int>::E : int { eint }; // OK
template<> enum class A<int>::S : int { sint }; // OK
template<class T> enum A<T>::E : T { eT };
template<class T> enum class A<T>::S : T { sT };
template<> enum A<char>::E : char { echar }; // error: A<char>::E was instantiated
// when A<char> was instantiated
template<> enum class A<char>::S : char { schar }; // OK
The comment in the last line says it's ok, however, doesn't A<char> cause the implicit instantiation of S? As per [temp.inst] p3
The implicit instantiation of a class template specialization causes
the implicit instantiation of the declarations, but not of the definitions, of the non-deleted class member functions, member classes, scoped member enumerations, static data members, member templates, and friends; and
the implicit instantiation of the definitions of deleted member functions, unscoped member enumerations, and member anonymous unions.
Hence, presumably, the intent of [temp.expl.spec] p7 does not merely refer to an implicit instantiation. Consider this case
template<class T> struct A {
enum E : T;
enum class S : T;
};
template<> enum A<int>::E : int { eint }; // OK
template<> enum class A<int>::S : int { sint }; // OK
// template<class T> enum A<T>::E : T { eT }; comment this definition
template<class T> enum class A<T>::S : T { sT };
template<> enum A<char>::E : char { echar }; // OK
template<> enum class A<char>::S : char { schar }; // OK
If we comment the definition of A<T>::E, then the explicit specialization template<> enum A<char>::E : char { echar }; is also ok(both in GCC and Clang), however, [temp.inst] p3 still applies(i.e implicitly instantiates) here regardless of whether A<T>::E has its definition or not. So, Is the following rule the original intent of [temp.expl.spec] p7?
If a template, a member template or a member of a class template is explicitly specialized, a declaration of that specialization shall be reachable from every use of that specialization that would cause an implicit instantiation of the definition to take place and the entity whose specialization is being implicit instantiated has been defined at the point of instantiation, in every translation unit in which such a use occurs; no diagnostic is required.
Full name of submitter (unless configured in github; will be published with the issue): Jim X
The original issue is https://github.com/cplusplus/draft/issues/4816
[temp.expl.spec]
Consider the formal example after the above rule
The comment in the last line says it's ok, however, doesn't
A<char>
cause the implicit instantiation ofS
? As per [temp.inst] p3Hence, presumably, the intent of [temp.expl.spec] p7 does not merely refer to an implicit instantiation. Consider this case
If we comment the definition of
A<T>::E
, then the explicit specializationtemplate<> enum A<char>::E : char { echar };
is also ok(both in GCC and Clang), however, [temp.inst] p3 still applies(i.e implicitly instantiates) here regardless of whetherA<T>::E
has its definition or not. So, Is the following rule the original intent of [temp.expl.spec] p7?