boost库有一个Any类,是一个特殊的只能容纳一个元素的容器,他可以擦除类型,给任何类型赋值。
boost::any a = 1;
boost::any a = 1.1;
std::vector<boost::any> v;
v.push_back(a);
v.push_back(b);
int va = boost::any_cast<int>(a);
...
关键点就是,需要擦除具体的类型,使用一种通用的方式保存所有的类型的数据,这里可以使用继承的方式实现,具体如下:
实现
class Any
{
public:
Any() : m_tpIndex(std::type_index(typeid(void))) {}
Any(Any& other) : m_ptr(other.clone()), m_tpIndex(other.m_tpIndex) {}
Any(Any&& other) : m_ptr(std::move(other.m_ptr)), m_tpIndex(std::move(other.m_tpIndex)) {}
//判断U是 Any类型还是模板类型
template<typename U,
class = typename std::enable_if<!std::is_same<typename std::decay<U>::type, Any>::value, U>::type>
Any(U&& value)
: m_ptr(new Derived<typename std::decay<U>::type>(std::forward<U>(value)))
, m_tpIndex(typeid(typename std::decay<U>::type)) {}
//判空
bool isNull()
{
return !bool(m_ptr);
}
//判断类型
template<typename T>
bool is()
{
return m_tpIndex == type_index(typeid(T));
}
//Any类 转换成具体的类
template<typename T>
T& cast()
{
if (!is<T>())
{
cout << "can not cast " << typeid(T).name() << " to "
<< m_tpIndex.name() << endl;
throw bad_cast();
}
auto derived = dynamic_cast<Derived<T>*>(m_ptr.get());
return derived->m_value;
}
Any& operator=(const Any& other)
{
if (m_ptr == other.m_ptr)
{
return *this;
}
m_ptr = other.clone();
m_tpIndex = other.m_tpIndex;
return *this;
}
private:
struct Base;
using BasePtr = std::unique_ptr<Base>;
//基类非模板用了擦除具体类型
struct Base
{
virtual BasePtr clone() const = 0;
};
//子类存放具体内容
template<typename T>
struct Derived : public Base
{
template<typename...Args>
Derived(Args&& ...args) : m_value(std::forward<Args>(args)...){}
BasePtr clone() const
{
return BasePtr(new Derived(m_value));
}
T m_value;
};
//构造函数使用 clone
BasePtr clone() const
{
if (m_ptr != nullptr)
{
return m_ptr->clone();
}
return nullptr;
}
BasePtr m_ptr; //记录实际值
std::type_index m_tpIndex; //记录值对应的内容
};
void testAny()
{
Any a = 1;
Any b = string("hello,world");
Any c;
cout << std::boolalpha;
cout << "a is null:" << a.isNull() << endl;
cout << "b is null:" << b.isNull() << endl;
cout << "c is null:" << c.isNull() << endl;
cout << endl;
cout << "a is int:" << a.is<int>() << endl;
cout << "a is string:" << a.is<string>() << endl;
cout << "a is void:" << a.is<void>() << endl;
cout << endl;
cout << "a = " << a.cast<int>() << endl;
cout << "b = " << b.cast<string>() << endl;
//cout << "c = " << c.cast<void>() << endl;
cout << endl;
//error
cout << "a = " << a.cast<string>() << endl;
vector<Any> v;
v.push_back(1);
v.push_back(1.2);
v.push_back(string("str"));
cout << v[1].cast<double>() << endl;
}
打印结果如下:
如果cast转换失败则会发生如下异常: