名称在类定义的一部分中引用基类成员并在另一部分中引用派生类成员是否合法?这段代码演示了它:
struct Base
{
typedef int T;
};
struct Derived : Base
{
T m1; //type int
typedef T *T;
T m2; //type int*
};
我无法在标准中找到反对这一点的裁决。代码合法吗?
名称在类定义的一部分中引用基类成员并在另一部分中引用派生类成员是否合法?这段代码演示了它:
struct Base
{
typedef int T;
};
struct Derived : Base
{
T m1; //type int
typedef T *T;
T m2; //type int*
};
我无法在标准中找到反对这一点的裁决。代码合法吗?
幸运的是,在这种情况下,它是否合法并不重要(我相信它的格式是正确的,因为 typedef 被允许隐藏),因为您可以进行微小的重构更改,并且代码变得非常明显:
struct Derived : Base
{
typedef Base::T BaseT;
typedef BaseT* T;
BaseT m1; //type int
T m2; //type int*
};
是的,这是合法的。我不会评论它是否可取。
首先,您需要能够在派生类中重新声明具有相同名称的不同实体;这是 3.3.10/1 允许的(我强调):
可以通过在嵌套声明区域或派生类中显式声明相同名称来隐藏名称。
然后你需要在声明中T
引用; 即此时一定不在范围内。范围由 3.3.3/1 定义:Base::T
Derived::T
Derived::T
它的潜在作用域从其声明点开始,并在其块的末尾结束。
声明点由 3.3.2/1 定义:
名称的声明点紧跟在其完整的声明符之后
这意味着,在声明符之前和期间,Derived::T
不在范围内,因此T
指的是Base::T
.
我相信它是合法的(typedef
当然是按照它们出现的顺序处理的),但是对于将来试图阅读代码的人来说,这将是非常混乱的。
重命名次要类型会更有意义:
typedef T *Tptr;
Tptr m2;