[英]C++ Get Vector type
我正在使用用於對象構造的模板函數從反射數據創建對象,並且它工作得很好,但現在我想在反射系統中支持 STL 容器類型,以便對象例如:
// 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 型
測試代碼的 pastebin 嘗試解決這個問題: http : //pastebin.com/1ZAw1VXg
所以我的問題是,當我在像這樣的模板中時,如何獲得 std::vector 聲明的 std::string 部分
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<>
(與所有標准庫容器類一樣)維護一個成員類型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);
}
在 c++11 中,你可以使用 decltype 和 std::decay 來達到這個效果:
std::vector<int> vec; using T = typename std::decay<decltype(*vec.begin())>::type;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.