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