4

当我遇到这篇文章时,我正在阅读别人的代码(剥离到 MWE):

template<typename R> class Test {
    public:
        typedef R R;
};

这里有一个typedef模板参数,它让 GCC 和 clang(有或没有-std=c++2a)抱怨:

test.cc:3:19: 错误: 'typedef R Test::R' 的声明阴影模板参数

但是,编译器资源管理器上的 ICC 和 MSVC都接受该部分。

我读过这个问题,建议 a typedefto self 通常是无操作的。但是,这里似乎并非如此。我也发现这个问题是相关的,但我认为它们应该不同,因为我们在这里使用的是typedef.

那么问题来了:
标准允许这种重新定义吗?该声明有任何副作用吗?为什么有人会这样写?

4

1 回答 1

4

不可以。模板参数的名称不允许重新声明

模板参数的名称不允许在其范围(包括嵌套范围)内重新声明。模板参数不允许与模板名称同名。

template<class T, int N>
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

根据标准,[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

——结束示例]

于 2021-07-13T02:12:46.363 回答