我使用模板函数来构造对象,从反射数据中创建对象,效果很好,但是现在我想在反射系统中支持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()
来判断一个对象是向量还是Map,以及这个对象的参数是什么,我尝试了一些模板魔术来做类似下面的事情,其中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::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>>>();
2条答案
按热度按时间8yparm6h1#
有两种方法可以实现这一点。
**1)**或者你可以利用
std::vector<>
(像所有标准库容器类一样)维护一个成员类型value_type
,它代表了存储在向量中的元素的类型。**2)**或者,您更改函数的声明并使用模板模板参数:
然而,这有一个小问题:
std::vector
实际上是一个有两个参数的模板(元素类型和分配器类型),这使得使用模板的模板参数并保持语法简单有点困难,对我来说,有一件事是有效的,那就是声明一个向量类型的别名,只留下一个模板参数:然后我可以像这样使用
SomeFunc
:wtzytmuj2#
在c++11中,你可以使用decltype和std::decay来达到这样的效果:
std::vector<int> vec; using T = typename std::decay<decltype(*vec.begin())>::type;