从模板类继承,类型在子类中声明

Inheriting from a template class, Types are declared in child class

本文关键字:子类 声明 类型 继承      更新时间:2023-10-16

我想要一个模板父类(虚拟)。子类从父类继承并在其内部定义类型。

// PARENT
template <typename A, typename B>
class Parent 
{
public:
    Parent();
    virtual ~Parent();
    // ...
};
// CHILD
class Child : public Parent<SomeStruct , AnotherStruct>
{
public:
    struct SomeStruct 
    {/*...*/};
    struct AnotherStruct
    {/*...*/};
    Child();
    ~Child();
    // ...
};

显而易见,编译器会抱怨尚未定义的"SomeStruct"。问题是如何实现类似的目标。一个简单的方法是在类之外定义结构,但这会让事情变得更加丑陋。

这是一个鸡和蛋的情况。编译器需要查看声明的结构,以便实例化Parent。

你可以试试这样的东西:

template <typename A, typename B>
class Parent 
{
public:
    Parent();
    virtual ~Parent();
    // ...
};
// CHILD
class ChildBase
{
    public:
    struct SomeStruct 
    {/*...*/};
    struct AnotherStruct
    {/*...*/};
};
class Child : public ChildBase, public Parent<ChildBase::SomeStruct, ChildBase::AnotherStruct>
{
public:
    using ChildBase::SomeStruct;
    using ChildBase::AnotherStruct;
    Child();
    ~Child();
    // ...
};

这走的是多重继承路线。或者,您可以将结构声明放在命名空间中,而不是基类中,因为基类不会将它们留在全局命名空间中。

这两种方法都不是您想要的,但如果您想要Child::SomeStruct类型的语法,则不会污染全局命名空间,并使类型在Child上可见。

您无法执行您正在尝试的操作。

可以正向声明类,但不能正向声明嵌套类。你必须重新考虑你的设计。

有一个解决方案可能会对您有所帮助。这并不完全像你正在做的事情,但它正在实现同样的事情。使用"策略"idom看看这个:

// PARENT
template <typename Policy>
struct Parent : Policy {
    Parent();
    virtual ~Parent();
    // ...
};
// CHILD POLICY
struct ChildPolicy {
    struct SomeStruct 
    {/*...*/};
    struct AnotherStruct
    {/*...*/};
}
// CHILD
struct Child : public Parent<ChildPolicy> {
    Child();
    ~Child();
    // Here you can use your two types 
    // ...
};

或者,如果您在Child中使用的类型在该类型的所有子级中都有一个良好的类型名称,您可以这样声明父级:

template <typename Policy>
struct Parent {
    using typename Policy::SomeStruct;
    using typename Policy::AnotherStruct;
    Parent();
    virtual ~Parent();
    // ...
};

我强烈推荐父的第二个解决方案