Can C++ struct static member variables shadow non type template parameters?

Viewed 402

msvc compiles the following code(with /permissive- compiler switch), clang and gcc do not:

template<auto val>
struct S{
    static constexpr auto val = val;
};
int main() {
    return S<4>::val;
}

I presume that this is just a msvc bug, but I am curious if maybe standard is ambiguous here.

2 Answers

The standard is unambiguous on this, a template parameter can't be redeclared for any reason, see [temp.local]/6:

A template-parameter shall not be redeclared within its scope (including nested scopes). A template-parameter shall not have the same name as the template name.

[ Example:

template<class T, int i> class Y {
  int T;            // error: template-parameter redeclared
  void f() {
    char T;         // error: template-parameter redeclared
  }
};

template<class X> class X;      // error: template-parameter redeclared

 — end example ]

So MSVC behavior (given the /permissive- flag) looks like a bug.

[temp.local]/6:

The name of a template-parameter shall not be bound to any following declaration contained by the scope to which the template-parameter belongs.

[Example 5:

template<class T, int i> class Y {
  int T;                                // error: template-parameter hidden
  void f() {
    char T;                             // error: template-parameter hidden
  }
  friend void T();                      // OK: no name bound
};

template<class X> class X;              // error: hidden by template-parameter

— end example]

A declaration of a static data member plainly binds a name, so it is just as ill-formed.

Related