是一个 typedef 允许通过模板参数

时间:2021-07-13 01:52:35

标签: c++ templates language-lawyer typedef noop

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

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

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

<块引用>

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

然而,Compiler Explorer 上的 ICC 和 MSVC 都接受了这一点。

我读过 this question,建议对 self 的 typedef 通常是空操作。然而,这里似乎并非如此。我还发现 this question 是相关的,但我认为它们应该有所不同,因为我们在这里使用的是 typedef

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

1 个答案:

答案 0 :(得分:3)

没有。模板参数的名称不允许为 redeclared

<块引用>

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

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

——结束示例]