我一直在重构,将成员从子类转移到共同的父类。
我想使用编译器警告/错误来防止子级和父级中出现相同的变量(如果我忘记从子级中删除)。
下面的代码会产生一个关于 Clang 16/17 的警告:
struct P
{
int a;
};
struct C : public P
{
int a;
};
int main()
{
return 0;
}
。
warning: non-static data member 'a' of 'C' shadows member inherited from type 'P' [-Wshadow-field]
然而,在我的情况下,我有一个模板化的层次结构:
template<class E>
struct P
{
int a;
};
template<class E>
struct C : public P<E>
{
int a;
};
int main()
{
C<double> c;
return 0;
}
这不会产生警告。为什么是这样?
这是依赖名称和模板专业化的结果。当你这样做时
你真正能做的就是检查它的语法是否正确。我们还不知道
E
现在是什么,所以我们也不知道P<E>
会变成什么。之后可能会引入一个专门针对没有成员的C
专业化,因此不会有成员隐藏。P
double
该警告是关于名称隐藏的,而不是关于重复的成员名称。当您有依赖基类时,不会将任何名称带入作用域,因此不会隐藏任何内容。
在非模板情况下:
在模板化的情况下:
Clang 根本不会对您当前想要执行的操作发出警告。