any-----安全存储任意类型

来源:互联网 发布:极客湾淘宝店 编辑:程序博客网 时间:2024/05/17 20:02

简单存储对象时候,用 string/void* 存储数据,类型不安全,丢失了类型信息。

补救的方式是设置一个 type 类型,但这很繁琐,不够自动化;而且 用string 序列化会损失性能。 


C++库默认有 type_id() 返回 type_info结构,这是天然的 type类型,自动拥有了对象类型信息。

利用模板技巧:

       class placeholder        {        public: // structors            virtual ~placeholder()            {            }        public: // queries            virtual const boost::typeindex::type_info& type() const BOOST_NOEXCEPT = 0;            virtual placeholder * clone() const = 0;        };        template<typename ValueType>        class holder : public placeholder
这是 any类内部指针实现的方式.

template<typename ValueType>        any(const ValueType & value)          : content(new holder<                BOOST_DEDUCED_TYPENAME remove_cv<BOOST_DEDUCED_TYPENAME decay<const ValueType>::type>::type            >(value))        {        }        any(const any & other)          : content(other.content ? other.content->clone() : 0)        {        }


基于any,可以存储任意类型:

using boost::any_cast;typedef std::list<boost::any> many;staticvoid append_int(many & values, int value){boost::any to_append = value;values.push_back(to_append);}staticvoid append_string(many & values, const std::string & value){values.push_back(value);}staticvoid append_char_ptr(many & values, const char * value){values.push_back(value);}staticvoid append_any(many & values, const boost::any & value){values.push_back(value);}staticvoid append_nothing(many & values){values.push_back(boost::any());}staticbool is_empty(const boost::any & operand){return operand.empty();}staticbool is_int(const boost::any & operand){return operand.type() == typeid(int);}staticbool is_char_ptr(const boost::any & operand){try{any_cast<const char *>(operand);return true;}catch(const boost::bad_any_cast &){return false;}}staticbool is_string(const boost::any & operand){return any_cast<std::string>(&operand);}staticvoid count_all(many & values, std::ostream & out){out << "#empty == "<< std::count_if(values.begin(), values.end(), is_empty) << std::endl;out << "#int == "<< std::count_if(values.begin(), values.end(), is_int) << std::endl;out << "#const char * == "<< std::count_if(values.begin(), values.end(), is_char_ptr) << std::endl;out << "#string == "<< std::count_if(values.begin(), values.end(), is_string) << std::endl;}JOB_DEFINE(boost_any , test2){many values;append_int(values , 5);append_nothing(values);append_string(values , "hello");append_any(values , boost::any(4.0));append_char_ptr(values , "world");count_all(values , std::cout );}

测试结果:

=====<boost_any_test2>begin#empty == 1#int == 1#const char * == 1#string == 1=====<boost_any_test2>end [State:OK] [Times:0.003s]

any非常有用,尤其是处理各种数据类型。

比void*强大安全




















原创粉丝点击