是否允许对模板参数使用 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]
当我看到这篇文章时,我正在阅读别人的代码(剥离到 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]