我有一个第三方API,其中定义了一百多种不同类型的结构以及一些基类数据。结构的数量及其类型可以在版本之间变化。
我需要动态创建和填充至少几十个这些结构的向量(每个向量包含一个结构类型)。访问(识别)这些向量的最明智的方法是根据其数据类型。
以下是我目前的做法。我无权使用C ++ 17。
我的问题是:我是否在这里自动涵盖所有内存管理? 我是否可以创建任何可以避免的不必要的副本?
#include "stdafx.h"
#include <iostream>
#include <memory>
#include <vector>
#include <unordered_map>
#include <typeinfo>
// from a third party API
struct A {
int a;
};
struct B {
int a;
};
// ----
#define mapHash map[typeid(T).hash_code()]
typedef std::unordered_map<size_t, std::shared_ptr<void>> omniMap;
template <class T>
void addVect(omniMap &map) {
if(mapHash == nullptr) {
mapHash = std::make_shared<std::vector<T>>();
}
T s{};
(*std::static_pointer_cast<std::vector<T>>(mapHash)).push_back(std::move(s));
}
template <class T>
std::shared_ptr<std::vector<T>> getVect(omniMap &map) {
return std::static_pointer_cast<std::vector<T>>(mapHash);
}
template <class T>
void addElem(omniMap &map, const T &var) {
mapHash = std::make_shared<T>(var);
}
template <class T>
std::shared_ptr<T> getElem(omniMap &map) {
return std::static_pointer_cast<T>(mapHash);
}
int main()
{
omniMap om;
addVect<A>(om);
addVect<A>(om);
addVect<B>(om);
addElem(om, 5);
addElem(om, 2.5);
addElem<std::string>(om, "hello");
*getElem<int>(om) = 3;
*getElem<double>(om) = 3.7;
(*getVect<A>(om))[1].a = 15;
std::cout <<
(*getVect<A>(om))[1].a << " " <<
*getElem<int>(om) << " " <<
*getElem<double>(om) << " " <<
(*getElem<std::string>(om)).c_str() << std::endl;
return 0;
}
output
15 3 3.7 hello
答案 0 :(得分:0)
您不必要地将编译时信息转换为运行时数据结构。不用了考虑这样的事情:
namespace internal {
template <typename T>
struct VectorHolder {
static std::vector<T> vect;
};
template <typename T> std::vector<T> VectorHolder<T>::vect;
}
template <typename T>
std::vector<T>& getVect() { return internal::VectorHolder<T>::vect; }
template <class T>
void addVect() {
getVect<T>().emplace_back();
}
// Other functions left as an exercise for the reader
编译器将在编译时按类型查找正确的向量。