Title
Declarative nested-name-specifier naming a partial specialization
Status
open
Section
7.5.5.3 [expr.prim.id.qual]
Submitter
Hubert Tong

Created on 2024-12-20.00:00:00 last changed 2 days ago

Messages

Date: 2024-12-21.13:36:56

Consider:

  template <auto AX> struct A;
  template <int AX> struct A<AX> {
   static constexpr int X = AX;
  };
  template <int AX> const int A<AX>::X;   // #1

According to 7.5.5.3 [expr.prim.id.qual] paragraph 3, the declarative nested-name-specifier at #1 names the primary template and is thus ill-formed:

... If a nested-name-specifier N is declarative and has a simple-template-id with a template argument list A that involves a template parameter, let T be the template nominated by N without A. T shall be a class template.
  • If A is the template argument list (13.4 [temp.arg]) of the corresponding template-head H (13.7.3 [temp.mem]), N nominates the primary template of T ; H shall be equivalent to the template-head of T (13.7.7.2 [temp.over.link]).
  • Otherwise, N nominates the partial specialization (13.7.6 [temp.spec.partial]) of T whose template argument list is equivalent to A (13.7.7.2 [temp.over.link]); the program is ill-formed if no such partial specialization exists.

However, the qualified-id is obviously intended to refer a member of the partial specialization.

Furthermore, the specification does not handle references to constrained partial specializations:

  template <typename T> struct A;
  template <typename T> concept C = true;

  template <typename T>
  requires C<T>
  struct A<T *> {
    struct B;
  };

  template <typename T>
  requires true && C<T>
  struct A<T *> {
    struct B;                   // #1
  };

  template <typename T>
  requires true && C<T>
  struct A<T *>::B {};         // ought to refer to #1
History
Date User Action Args
2024-12-20 00:00:00admincreate