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 错误,但我很好奇这里的标准是否有歧义。
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-
标志)看起来像一个错误。
msvc 编译以下代码(使用 /permissive- 编译器开关)、clang 和 gcc do not:
template<auto val>
struct S{
static constexpr auto val = val;
};
int main() {
return S<4>::val;
}
我认为这只是一个 msvc 错误,但我很好奇这里的标准是否有歧义。
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-
标志)看起来像一个错误。