【问题标题】:Can C++ struct static member variables shadow non type template parameters?C++ struct 静态成员变量可以隐藏非类型模板参数吗?
【发布时间】:2021-10-13 04:48:44
【问题描述】:

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

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

我认为这只是一个 msvc 错误,但我很好奇这里的标准是否模棱两可。

【问题讨论】:

  • 我的理解(在使用 GCC 编译 MSVC 代码时遇到这个问题)是 MSVC 将其作为扩展。
  • 你应该在你的问题中提到MSVC用/permissive-成功编译了这个(根据你的godbolt链接)。这是一个重要的细节。
  • report the bug的建议
  • @Frank 固定,ty

标签: c++ language-lawyer c++20 non-type-template-parameter


【解决方案1】:

标准对此很明确,模板参数不能以任何理由重新声明,见[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- 标志)看起来像一个错误。

【讨论】:

  • 如果我有一个猜测...MSVC 将T 视为类型名,因此不会因为类型和声明之间的名称分离而失败...但是标准中的示例是明确的错了。
【解决方案2】:

[temp.local]/6:

template-parameter 的名称不应与以下任何内容绑定 模板参数的范围所包含的声明 属于。

[示例 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

——结束示例]

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-10-16
    • 1970-01-01
    • 2011-08-15
    • 1970-01-01
    • 1970-01-01
    • 2018-11-15
    • 1970-01-01
    相关资源
    最近更新 更多