如何将对象与其类型关联

How to associate object with its type

本文关键字:类型 关联 对象      更新时间:2023-10-16

我正在尝试用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)只创建一个模板类然后从那里开始。那么,有可能做我想做的事情吗?如果有,我该怎么做?

根据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库已经实现的代码。

编辑:感谢千禧虫指出boost::any已经存储了std::type_info