简体   繁体   English

C++ 获取向量类型

[英]C++ Get Vector type

I'm using template functions for object construction to create objects from reflection data, and it works pretty well, but now I want to support STL container types in the reflection system so that objects such as:我正在使用用于对象构造的模板函数从反射数据创建对象,并且它工作得很好,但现在我想在反射系统中支持 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;
};

Can be supported.可以支持。 I can do some regex magic on the return of我可以在返回时做一些正则表达式魔术

typeid( object ).name() 

to figure out if an object is a vector or a map, and what the parameter arguments for the object is.确定对象是向量还是地图,以及对象的参数参数是什么。 And I have tried some template magic to do it something like the following, where CreateString, ConstructString & DestroyString are stand in functions and the data is stand in as well for something a bit more complex that uses a type database to handle object construction.我已经尝试了一些模板魔术来做到这一点,如下所示,其中 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);

}

Which doesn't work owing to the illegal indirection with "vec->push_back(*obj);"由于“vec->push_back(*obj);”的非法间接访问,这不起作用which I can't case because I don't actually know the type.我不能这样做,因为我实际上不知道类型。 Basically what I need to be able to do is create this vector with some blank unset elements already in it, or add new elements to it without actually having the type, because if I can get a pointer to a memory block inside the vector I can roll with that and construct the object.基本上我需要能够做的是创建这个向量,其中已经有一些空白的未设置元素,或者在没有实际类型的情况下向它添加新元素,因为如果我能得到一个指向向量内的内存块的指针,我就可以滚动并构建对象。 But the vector add requirements such as但是向量添加了要求,例如

vector::push_back( T& value ) 

or要么

vector::insert( Iter&, T& ) 

Won't work for me unless I can get my hands on that T type from inside the template对我不起作用,除非我可以从模板内部接触到那个 T 型

pastebin of testing code to try and solve this: http://pastebin.com/1ZAw1VXg测试代码的 pastebin 尝试解决这个问题: http : //pastebin.com/1ZAw1VXg

So my question is, how can I get the std::string part of a std::vector declaration when I'm inside a template like所以我的问题是,当我在像这样的模板中时,如何获得 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>>>();

There are two ways to accomplish this.有两种方法可以实现这一点。

1) Either you make use of the fact that std::vector<> (like all standard library container classes) maintains a member type value_type , which represents the type of the elements stored in the vector. 1)要么利用std::vector<> (与所有标准库容器类一样)维护一个成员类型value_type ,它表示存储在向量中的元素的类型。 So you can do this:所以你可以这样做:

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

2) Or else, you change the declaration of your function and make use of template template parameters: 2)否则,您更改函数的声明并使用模板模板参数:

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

However, there is a small problem with that: std::vector is really a template with two parameters (element type and allocator type), which makes it a little difficult to use the template template parameters and still keep the syntax simple.但是,有一个小问题: std::vector实际上是一个带有两个参数(元素类型和分配器类型)的模板,这使得使用模板模板参数并保持语法简单有点困难。 One thing that worked for me is to declare an alias of the vector type that leaves only one template parameter:对我有用的一件事是声明一个仅留下一个模板参数的向量类型的别名:

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

Then I can use SomeFunc like this:然后我可以像这样使用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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM