2014-02-13 83 views
2

假設我有一個模板類如何在模板類創建的類型名稱通新類型名

template <class DATA> 
class Stack { 
    //Some implementation 
} 

這裏面堆棧類我打電話的實用程序類,這也是模板。但是數據類型的處理是UltityDATA類型的。也就是說,如果我們創建一個使用下面的代碼

stack<MyData> s 

內部,它應該叫UltityMyData等級堆棧的對象。我不想向客戶展示UltityMyData結構。我已經編寫了將MyData轉換爲UltityMyData的實現。只有我的要求是當我調用我的庫類時,如何將DATA typename轉換爲UtilityDATA typename。


我已經wrritten下面的代碼按你的建議

#include <iostream> 
#include <vector> 
#include <cstdlib> 
#include <string> 
#include <stdexcept> 

using namespace std; 
struct RTI 
{ 
    int a; 
}; 

struct DDSRTI 
{ 
    int b; 
}; 

// other specialization you might need in the future 
template<class Data> 
struct DDS 
{ 
    typedef DDSData type; 
}; 
template <class T> 
class MyStack { 
    private: 
    T a; 
    public: 
     MyStack() 
     { 
     // cout<< a; 
     } 
}; 
#define STACK(T) Stack<DDS##T> 
template <class T> 
class Stack { 
    private: 
    Stack<T> a; 
    STACK(T) b; 
    public: 
     Stack() 
     { 
     ///cout<< a; 
     } 
}; 

但我得到錯誤的錯誤:「DDST」在此範圍內未聲明
基本上預處理只追加兩個值並創建一個新的類型。根據我的理解模板將在編譯時轉換。 DDS#T將其作爲新的數據類型而不是模板類型。

+2

'UtilityMyData'也被設計爲模板類嗎?如果你展示了這個聲明會很有幫助。 –

+0

不,這是不可能的,模板類(您的案例中的Stack)不知道用於實例化的實際類型,所以在C++語言中沒有辦法允許這樣做。 –

回答

0

你可以有一個結構,專門類型定義根據您的需要

// non specialized type 
template<typename T> 
struct UtilType {}; 

// specialization for DATA 
template<> 
struct UtilType<DATA> 
{ 
    typedef UtilityDATA type; 
}; 

// other specialization you might need in the future 
template<> 
struct UtilType<NewType> 
{ 
    typedef UtilityNewType type; 
}; 

你會再使用此助手類如此

template<typename T> 
class Stack 
{ 
    // ..... 
    typedef typename UtilType<T>::type dataType; //converts DATA typename to UtilityDATA 
    // ..... 
} 
0

你可以使用一個traits模式:

template <class DATA, class TRAITS> 
class Stack 
{ 
    //Some implementation 
} 

和實例化這樣的:

stack<MyData, UtilityMyData> s; 

然而,這將要求用戶明確命名的實用工具類。如果你不介意使用預處理器,你可以使用宏:

#define STACK(T) Stack<T, Utility##T> 

然後你會寫:

STACK(MyData) s; 

它不漂亮,但它可能是可以接受的用戶

+0

爲什麼一個宏!那太糟了。就像所有標準庫容器一樣,使用默認的模板參數 – Manu343726

+0

@Manu343726-是的宏是可怕的,但是如果你看了這個問題,你會發現你不能使用默認的模板參數 – Sean

+0

不,只是說UtilityMyData有不要暴露於公衆。創建一個類似'default_data'的標籤類型,將其用作默認參數,並且內部使用它來選擇UtilityMyData或不使用(例如使用std :: conditional) – Manu343726

0

也許你可以把它移動到一些內部模板結構?

template <class DATA> 
class Stack { 
    public: 
    template <class Data> 
     struct UtilData { 
     template <class... Args> 
      UtilData(Args&&... args) : d{std::forward<From>(args)...} {} 
      // other operators 
      Data d; 
     }; 

    void push(DATA&& d) { 
     s.push(UtilData<DATA>{d}); 
    } 
    std::stack<UtilData<DATA>> s; 
}; 

更新:對不起,我誤解了你的問題。對於某些具體類型邁德特和UtilMyData你可以使用boost :: MPL ::地圖:

using boost::mpl::pair; 
using boost::mpl::map; 
using boost::mpl::at; 

typedef map<pair<SomeOther, Some>/*, other pairs of types here*/> TypeMap; 

at<TypeMap, SomeOther>::type s; // s has type Some