2012-09-19 146 views
6

我使用模板函數進行對象構造以從反射數據創建對象,並且工作得非常好,但是現在我想在反射系統中支持STL容器類型,以便諸如以下對象:C++獲取矢量類型

// Note - test case only 
// for real world usage it would probably not be structured like this 
// and the phrases would be mapped by an id or something 
struct Phrases { 
    std::vector<std::string> phrases; 
}; 

typedef std::string Lang; 
struct Langs { 
    std::map< Lang, Phrases > translations; 
}; 

可以支持。我可以做的

typeid(object).name() 

回報一些正則表達式魔術弄清楚,如果對象是一個載體或地圖,什麼參數參數的對象。我已經嘗試了一些模板魔術來做下面的事情,其中​​CreateString,ConstructString & DestroyString是站在功能和數據是站在以及一些更復雜的東西,使用類型數據庫來處理對象的構造。

// Representational of code, basically a copy-paste to a different test project where I can work out the problems with this specific vector problem 
// Vector specialised construction 
template <typename T> void ConstructVector(void* object, const std::vector<std::string>& data) { 
    T* vec = (T*)object; 
    Name vector_type = GetVectorTypeName<T>(); 

    void *obj; 
    CreateString(&obj); 
    // All fields in this type should be valid objects for this vector 
    for(std::vector<std::string>::const_iterator it = data.begin(), end = data.end(); it != end; ++it) { 
    // Push it 
    vec->push_back(*obj); 
    // Get address to new instance 
    void *newly = &vec->back(); 
    ConstructString(newly,*it); 
    } 
    DestroyString(&obj); 

} 

其中由於非法間接與不工作 「vec->的push_back(* OBJ);」我不能這樣做,因爲我實際上並不知道這種類型。基本上我需要做的就是創建這個向量,其中已經有一些空白的未設置元素,或者添加新的元素而沒有實際的類型,因爲如果我可以得到指向內存塊的指針,我可以用它滾動並構建對象。但是,向量添加要求,如

vector::push_back(T& value) 

vector::insert(Iter&, T&) 

不會爲我工作,除非我可以在模板

引擎收錄的測試代碼中得到我的手說T形試圖解決這個問題: http://pastebin.com/1ZAw1VXg

所以我的問題是,我怎樣才能得到一個std ::向量聲明的字符串部分當我在模板內部時

template <typename T> void SomeFunc() { 

    // Need to get std::string here somehow  
    // Alternatively need to make the vector a certain size and then 
    // get pointers to it's members so I can construct them 
} 


SomeFunc<std::vector<std::string>>>(); 
+1

的'的std :: VECTOR'如果你需要的話,它有一個內部的'typedef T value_type'。 –

回答

15

有兩種方法可以實現此目的。

1)要麼你利用以下事實:std::vector<>(像所有標準庫的容器類)保持構件類型value_type,其表示存儲在矢量中的元素的類型。所以,你可以這樣做:

template <typename T> void SomeFunc() { 
    typename T::value_type s; // <--- declares a `std::string` object 
          //  if `T` is a `std::vector<std::string>` 
} 

2)否則,你改變你的函數的聲明和使用模板的模板參數:

template <template <typename> class T, typename Elem> 
void SomeFunc(T<Elem> &arg) 
{ 
    Elem s; 
} 

然而,有一個小問題,即:std::vector實際上是一個具有兩個參數(元素類型和分配器類型)的模板,這使得使用模板模板參數有點困難,並且仍然保持語法簡單。爲我工作的一件事是,宣佈只剩下一個模板參數向量類型的別名:

template <typename Elem> 
using myvector = std::vector<Elem>; 

那麼我可以用SomeFunc這樣的:

int main() 
{ 
    myvec<std::string> vec; 
    SomeFunc(vec); 
} 
+0

感謝你的這一點,它可以讓我製作出比我入侵的解決方案更乾淨的版本。 – kyall