Is a typedef to self allowed over template parameters

186 Views Asked by At

I was reading someone else's code when I came across this piece (stripped to MWE):

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

Here there is a typedef of the template parameter to itself, and it made GCC and clang (with or without -std=c++2a) complain:

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

However, ICC and MSVC on Compiler Explorer both accept that piece.

I've read 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 to be related but I think they should be different since here we are using a typedef.

So here is the question:
Is this kind of redefinition allowed by the standard? Are there any side effects of that statement? Why might one write that?

1

There are 1 best solutions below

0
leslie.yao On BEST ANSWER

No. The name of a template parameter is not allowed to be 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

From the standard, [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]