如何将对象与其类型

时间:2016-04-12 19:12:43

标签: c++

我正在尝试用C ++创建一个统计系统,它允许我将一个字符串与一个任意类型的值相关联。目前,我使用enum来跟踪类型以及指向对象的void *,但这需要我为所有类型制作单独的if语句我想支持。我想拥有它,以便我可以使用某种模板支持任意类型。我已经创建了一些有用的测试代码,但是存在一些问题:

class Test {
    std::type_index type;
    void *value;

public:
    template <typename T>
    Test(T val) : type(typeid(val)) {
        T *val_p = new T;
        *val_p = val;
        value = (void *)val;
    }

    Test() : type(typeid(void)) {
        value = nullptr;
    }

    ~Test() {
        //no idea how I could make this work
    }

    template <typename T>
    T get() {
        if (std::type_index(typeid(T)) == type) {
            T *val_p = (T *)value;
            return *val_p;
        } else {
            throw std::bad_typeid();
        }
    }
};

到目前为止我的工作,但我认为不可能实现析构函数或复制/移动构造函数。重点是我想将这一切存储在一个std::unordered_map中,所以我不能(AFAIK)只是创建一个模板类并从那里开始。那么,有可能做我想做的事情,如果是的话,我该怎么做呢?

1 个答案:

答案 0 :(得分:0)

根据GManNickG的建议,我跟boost::any一起去,因为它与我正在寻找的内容非常相似。

我还没有在代码中实现它,但基本结构将是:

#include <typeinfo>
#include <boost/any.hpp>

class Statistic {
    boost::any value;

public:
    template <typename T>
    Statistic(T val) : value(val) {}

    Statistic() : value() {}

    template <typename T>
    bool checkType() {
        return typeid(T) == value.type();
    }

    //Will cause an exception if the type doesn't match
    //Caller should check type if unsure
    template <typename T>
    T get() {
        if (checkType<T>()) {
            return boost::any_cast<T>(value);
        } else {
            //throw some exception
            throw bad_any_cast();
        }
    }
}

有了这个,我不需要处理析构函数或复制/移动函数,因为隐式函数会调用已经由boost库实现的代码。

编辑: 感谢milleniumbug指出boost::any已存储std::type_info