2015-11-03 89 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(); 
    // ... 
}; 

我強烈推薦第二個解決方案父