如何使用一个容器处理不同类型的数据?

时间:2018-10-14 05:30:58

标签: c++ visual-c++

我有一个第三方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

1 个答案:

答案 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

编译器将在编译时按类型查找正确的向量。