C++ 可以构造静态成员变量来隐藏非类型模板参数吗?

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

msvc 编译以下代码(使用 /permissive- 编译器开关)、clang 和 gcc do not:

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

我认为这只是一个 msvc 错误,但我很好奇这里的标准是否有歧义。

[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]

静态数据成员的声明显然绑定了一个名称,因此它也是格式错误的。

标准对此没有歧义,模板参数不能因任何原因重新声明,参见 [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 ]

所以 MSVC 行为(给定 /permissive- 标志)看起来像一个错误。