您的位置:首页 > 其它

浅尝BOOST之ANY

2017-01-07 21:36 351 查看
转自:http://www.cnblogs.com/wuerping/articles/116414.html

any是个很短小的类, 代码加上空行和说明也就187行,但很有意思。它的主要作用是定义一个变量来存放任意类型数据。 这方面我们多少有些经验,MS的tagVARIANT结构相信不少人都用过。tagVARIANT能用,有用,但不好用,通过variant_t包装后感觉才好一些,但仍旧有些别扭。any类让人感到比较自然,建议大家使用,下面先看一看示例:  

   
  最常见的用法 


        any a(100); 


        cout << any_cast<int>(a) << " : " <<  a.type().name() << endl; 


        any b(string("hello")); 


        cout << any_cast<string>(b) << " : " << b.type().name()  << endl; 


        b = a; 


        cout << any_cast<int>(a) << " : " << b.type().name()  << endl;

  另一种用法,  定义名字-值对(name-value pairs) 


        struct property 


        { 


            property(); 


            property(const std::string &, const boost::any &); 


 


            std::string name; 


            boost::any value; 


        }; 


        typedef std::list<property> properties;
    
  基于回调函数的运行时多态 
 


        class consumer 


        { 


        public: 


            virtual void notify(const any &) = 0; 


            

 


        };
    
      若是自已考虑实现一个这样的类,最开始可能会想到union方式的实现,tagVARIANT就用 这种方法实现。对模板熟悉的人则会第一时间考虑到使用模板,对于第一感,这里给出一段代码, 此段代码摘至  Conversations: I'd Hold Anything for You  (Jim Hyslop
and Herb Sutter) 此文介绍了any。文中的Guru的一句台词就是"You need any.",懒得写一段了,呵呵。 


        template <typename ValueType> 


        class multiType 


        { 


            ValueType value_; 


        public: 


            multiType(const ValueType &t) : value_(t) {}  


            operator ValueType() { return value_; } 


        };
  
     但是,一个此类变量会在其生命周期内改变值(在脚本语言多有这样的体会),这种写法做出来的是无法完成的。  
  
      那any类是如何实现的? 还是模板,但多了一些技巧。  
      前面的例子让我们看到,直接用模板是不现实的,那么我们需要一个间接层。第一点便是要避免 ValueType value_ 这种形式的代码,这好办,在类中加入一个纯虚基类;第二点,写出any a(100)  形式的表达式,呵,模板的实参推导(deduction)可以帮忙。去掉类型信息,去掉any_cast,去掉赋值(虽然我刚才提到这一点)...,我给出一个更加短小的简化版本的any(只有三十几行代码),大家可以看一看是如何实现的。当然看完了这个应该去any.hpp看一看,以防被误导
:P  


        class any 


        { 


        public: 


            template<typename _T> 


                any(const _T& value): _content(new holder<_T>(value)) 


            { 


            } 


            ~any() 


            { 


                delete _content; 


            } 


            class placeholder 


            { 


            }; 


        public: 


            template<typename _T> 


            class holder: public placeholder 


            { 


            public: 


                holder(const _T& value): _held(value) 


                { 


                } 


                _T _held; 


            }; 


            placeholder* _content;     


        }; 


 


        int main() 


        { 


            any a(100); 


            cout << ((any::holder<int>*)(a._content))->_held << endl;  


            any b(string("string")); 


            cout << ((any::holder<string>*)(b._content))->_held << endl;  


            return 0; 


        } 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: