是否允许对模板参数使用 self 的 typedef

Is a typedef to self allowed over template parameters

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

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

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

test.cc:3:19: error: declaration of 'typedef R Test::R' shadows template parameter

然而,Compiler Explorer 上的 ICC 和 MSVC 都接受该片段。

我读过 this question, and it is suggested that a typedef to self is usually a no-op. However, here it does not seem to be the case. I've also found this question 是相关的,但我认为它们应该有所不同,因为这里我们使用的是 typedef

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

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

The name of a template parameter is not allowed to be redeclared within its scope (including nested scopes). A template parameter is not allowed to have the same name as the template name.

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

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]