C++获取向量类型

szqfcxe2  于 2023-03-05  发布在  其他
关注(0)|答案(2)|浏览(133)

我使用模板函数来构造对象,从反射数据中创建对象,效果很好,但是现在我想在反射系统中支持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>>>();
8yparm6h

8yparm6h1#

有两种方法可以实现这一点。

**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()
{
  myvector<std::string> vec;
  SomeFunc(vec);
}
wtzytmuj

wtzytmuj2#

在c++11中,你可以使用decltype和std::decay来达到这样的效果:
std::vector<int> vec; using T = typename std::decay<decltype(*vec.begin())>::type;

相关问题