2015-11-03 92 views
2

我想拥有一个模板父类(虚拟)。子类从父类继承并定义其自身的类型。继承自模板类,在子类中声明类型

// 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”。问题是如何实现类似的东西。一个简单的方法是定义班级以外的结构,但这会让事情变得更加丑陋。

回答

3

它的鸡和鸡蛋的情况。编译器需要来查看声明的结构,以便它可以实例化父。

你可以尝试这样的:

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上留下类型。

+0

看起来更好,然后在全局命名空间中声明这两个结构。 :) –

2

你不能做你正在尝试的。

你可以转发声明一个类,但你不能转发声明一个嵌套类。你将不得不重新考虑你的设计。

+0

感谢,则要类外声明结构即可。 :/ –

1

有一种解决方案可以帮助你。 它不完全像你正在做的,但它实现了同样的事情。 它是利用“政策” 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 
    // ... 
}; 

另外,如果您使用的是子类型具有跨类的所有孩子一个完善的类型名称,你可以声明像这样的家长:

template <typename Policy> 
struct Parent { 

    using typename Policy::SomeStruct; 
    using typename Policy::AnotherStruct; 

    Parent(); 
    virtual ~Parent(); 
    // ... 
}; 

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