当我看到这篇文章时,我正在阅读别人的代码(剥离为 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
。
那么问题来了:
标准允许这种重新定义吗?
该声明有任何副作用吗?为什么有人会这么写?
答案 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
——结束示例]