C++struct静态成员变量可以隐藏非类型模板参数吗?
msvc 编译以下代码(使用 /permissive- 编译器开关),clang 和 gcc不会:
template<auto val>
struct S{
static constexpr auto val = val;
};
int main() {
return S<4>::val;
}
我认为这只是一个 msvc 错误,但我很好奇这里的标准是否含糊不清。
回答
标准对此是明确的,不能出于任何原因重新声明模板参数,请参阅[temp.local]/6:
模板参数不得在其范围内(包括嵌套范围)重新声明。模板参数不应与模板名称具有相同的名称。
[? 例子:
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? —?结束示例?]
所以 MSVC 行为(给定/permissive-标志)看起来像是一个错误。
回答
[temp.local]/6 :
模板参数的名称不应绑定到模板参数所属范围包含的任何后续声明。
[示例 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—结束示例]
静态数据成员的声明显然绑定了一个名称,因此它同样是格式错误的。