【C++11】Any类的实现
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&a
·
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(const 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)) {}
//通用的右值构造
template<class T, class = typename std::enable_if<!std::is_same<std::decay<T>::type, Any>::value, T>::type>
Any(T&& t)
: m_ptr(new Derived<std::decay<T>::type>(std::forward<T>(t)))
, m_tpIndex(typeid(std::decay<T>::type)) {}
//判断是否为空
bool isNull()
{
return !bool(m_ptr);
}
//是否可以类型转换
template<class T>
bool is()
{
return m_tpIndex == type_index(typeid(T));
}
//类型转换
template<class T>
T& cast()
{
if (!is<T>())
{
cout << "can not cast " << typeid(T).name() << " to "
<< m_tpIndex.name() << endl;
throw bad_cast();
}
auto ptr = dynamic_cast<Derived<T>*>(m_ptr.get());
return ptr->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;
};
//拷贝使用
BasePtr clone() const
{
if (m_ptr)
{
return m_ptr->clone();
}
return nullptr;
}
BasePtr m_ptr; //具体数据
std::type_index m_tpIndex; //数据类型
};
Any类测试
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 cast to int:" << a.cast<int>() << endl;
cout << "----------------------" << endl;
c = a;
cout << "c is int:" << c.is<int>() << endl;
cout << "c is string:" << c.is<string>() << endl;
cout << "c cast to int:" << c.cast<int>() << endl;
cout << "c cast to string:" << c.cast<string>() << endl;
}
运行可以得到如下的结果:
可以看到程序抛出了异常,所以在使用时需要注意一定要先判断在使用。
更多推荐
已为社区贡献1条内容
所有评论(0)