浅尝BOOST之ANY

来源:互联网 发布:希尔排序算法代码 编辑:程序博客网 时间:2024/05/17 06:58

转自: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; 
        }
 
0 0
原创粉丝点击