2011-08-22 73 views
4

我有兩個類。在成員變量中保存任何一種C++模板類

第一類(A)是用模板構建的。

template <class T> 
class A 
{ 
    public: 
     T value; 
}; 

第二個類(B)應該有一個類A的對象作爲成員變量。就像這樣:

但現在我想用任何一種模板類的A類不僅INT。 顯然我不能聲明一個包含任何種類的(成員變量)變量。 所以,我需要這樣的:

class B 
{ 
    public: 
     A<*> value; 
}; 

是否有此問題的任何(乾淨)解決方案?

- 來自德國的問候,巴斯蒂安

+1

爲什麼你需要這樣的事情? [描述目標,而不是步驟](http://www.catb.org/esr/faqs/smart-questions.html#goal)。 – GManNickG

回答

6

不能有一個單一的類B用「任何」成員對象,因爲B必須是良好定義的類,並A<T>是對於不同類型的T一個不同類型。您可以讓B模板本身:

template <typename T> 
class B 
{ 
    A<T> value; 
}; 

,或者你可以看看boost::any,它的類型是擦除容器中任意類型的(但利用它需要一定量的額外的工作)。 any類只適用於類型,但它並不完全是任意的。

+0

「類型擦除」?真? 'any_cast'如何在沒有類型的情況下工作? – Nim

+0

@Nim:「type-erasing」,意思是「any」對象的類型不取決於您放入的東西的類型。與'shared_ptr '比較,可以使用自定義刪除器自定義分配器,兩者都不成爲類型的一部分。 –

+0

@Nim:類型擦除類的講述是一個私有嵌套多態類,從中派生了模板化的子類。看看'any.hpp',這就是發生了什麼事情(叫做'placeholder')。 –

2

我想你有兩種選擇。首先是通過實例變量的類型參數參數化類:

template <class T> struct B 
{ 
    A<T> value; 
}; 

另一種選擇是聲明valuevoid*指針。 (但這可能不是你想要的)。

3

最簡單的解決方案將是使所有A從通用接口變種ineherit,即使它是空的:

class IA{} 

template <class T> 
class A : public IA 
{ 
    public: 
     T value; 
}; 

class B 
{ 
    public: 
     IA* value; 
}; 

現在,相關的成本:與價值

  • 互動僅​​限於IA接口;
  • 如果您嘗試轉換以獲取實際類型,那意味着您知道實際類型,因此它是沒有用的,並且使A類型參數爲B變得更容易使用。
  • 有關聯的運行期間繼承的運行成本

優勢:

  • 它很容易被其他開發人員理解
  • 它自然限制的類型可能對一些特定的
  • 它穿上」 t使用提升(有時,你不能)

所以要做得更好還有其他更簡單的解決方案,但這些解決方案很簡單:

如果您可以使用boost,boost :: any,boost :: variant和boost :: mpl可能是解決方案的基礎。

提升任何可以用作void *的安全替代品。唯一的問題是你可以有任何類型,比如類型是B類的模板參數。

如果您知道A可以是所有類型,則可以成功使用Boost變體。

如果您只想設置可能的類型列表並確保您的成員僅適用於他們,MPL可能會有所幫助。你可以用MPL做很多事情,所以它確實取決於你的確切需求。

1

我認爲這有助於理解模板類爲您使用的每種類型創建一個全新的分離類。例如,Vector<int>Vector<float>與類VectorIntVectorFloat是分開的。

對於B類,你基本上是問的value變量或者是A<int>A<float>,這等於說你想要的值要麼是「A_int」或「A_float」。爲了完成你......好吧,請使用另一個模板!