Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[temp.expl.spec] p7 merely implicit instantiation? #4816

Open
xmh0511 opened this issue Aug 16, 2021 · 0 comments
Open

[temp.expl.spec] p7 merely implicit instantiation? #4816

xmh0511 opened this issue Aug 16, 2021 · 0 comments

Comments

@xmh0511
Copy link
Contributor

xmh0511 commented Aug 16, 2021

[temp.expl.spec]

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 remark says the last line is ok. Isn't that A<char> doesn't 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 refer to an arbitrary implicit instantiation. Consider the second 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). 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant