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?
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]