boost::any

类别:编程语言 点击:0 评论:0 推荐:

发信人: flier (小海 (:好日子不多了:)), 信区: Programming
标  题: boost::any
发信站: BBS 水木清华站 (Mon May 13 12:02:24 2002)

我来抛砖,有人跟进吗?:)

boost::any

  boost::any是一个很有趣的类,刚刚开始我还以为其就是一个variant类型,
能够将任意类型值保存进去,能够以任意类型值读出来,不过我错了 :(
  boost::any的作者认为,所谓generic type有三个层面的解释方法:
  1.类似variant类型那样任意进行类型转换,可以保存一个(int)5进去,
    读一个(string)"5"出来。Win下面的VARIANT类型是以一个巨大的
    union实现的类似功能,使用灵活但效率较低
  2.区别对待包含值的类型,保存一个(int)5进去,不会被隐式转换为
    (string)'5'或者(double)5.0,这样效率较高且类型安全,
    不必担心ambiguous conversions
  3.对包含值类型不加区别,例如把所有保存的值强制转换为void *保存
    读取时再有程序员判断其类型。这样效率虽最高但无法保证类型安全
  boost::any就选择了第二层面的设计思路,它允许用户将任意类型值保存
进一个any类型变量,但内部并不改变值的类型,并提供方法让用户在使用时
主动/被动进行类型判断。

  在实现方面,boost::any使用两层内部类placeholder和holder保存
实际类型的值。类placeholder只是一个接口,模板类holder是特定类型
的实现。其中type()方法获取实际值类型,即typeid(ValueType);
clone()方法获取值的拷贝return new holder(held);
  virtual const std::type_info & type() const
  virtual placeholder * clone() const
  其值的类型信息不象Win的VARIANT那样以专门的字段保存,
而是通过模板参数形式静态保存。这样效率更高(仅在编译期),

通用性更强(任何类型都可以,真正any)但灵活性不如VARIANT
  在进行拷贝构造/赋值/swap时,都直接将整个placeholder换掉,
这样可以保证值类型的延续性。

  在使用方面,提供了主动/被动进行类型检测的方法。
  可以使用any::type()方法主动检测值类型
bool is_int(const boost::any & operand)
{
    return operand.type() == typeid(int);
}
  也可以通过any_cast函数被动进行检测。此函数与C++中的*_cast
系列关键字有相同的语法规范,尝试进行类型转换,如类型不匹配则对
指针转换返回NULL,对引用转换抛出boost::bad_any_cast异常
  在实现方面,boost::any使用两层内部类placeholder和holder保存
实际类型的值。类placeholder只是一个接口,模板类holder是特定类型
的实现。其中type()方法获取实际值类型,即typeid(ValueType);
clone()方法获取值的拷贝return new holder(held);
  virtual const std::type_info & type() const
  virtual placeholder * clone() const
  其值的类型信息不象Win的VARIANT那样以专门的字段保存,
而是通过模板参数形式静态保存。这样效率更高(仅在编译期),

通用性更强(任何类型都可以,真正any)但灵活性不如VARIANT
  在进行拷贝构造/赋值/swap时,都直接将整个placeholder换掉,
这样可以保证值类型的延续性。

  在使用方面,提供了主动/被动进行类型检测的方法。
  可以使用any::type()方法主动检测值类型
bool is_int(const boost::any & operand)
{
    return operand.type() == typeid(int);
}
  也可以通过any_cast函数被动进行检测。此函数与C++中的*_cast
系列关键字有相同的语法规范,尝试进行类型转换,如类型不匹配则对
指针转换返回NULL,对引用转换抛出boost::bad_any_cast异常
  boost::any str = string("12345");
  try
  {
    cout << boost::any_cast<int>(str) << endl;
  }
  catch(boost::bad_any_cast e)
  {
    cerr << e.what() << endl;
  }


  在应用方面,any类型适合于类型不同但使用相关的值。如C++的...
形式的函数参数本事不是类型安全的,可以通过vector<any>改造之
然后在使用时检测类型是否匹配,如可改造printf为
  void safe_printf(const char *format, const vector<any>& params)
  {
    int index = 0;
    for(const char *pch = format; *pch; pch++)
    {
      switch(*pch)
      {
        case '%':
        {
          switch(*++pch)
          {
            case 'i':
            case 'd':
            {
              if(params[index].type() == typeid(int) ||
                 params[index].type() == typeid(short))
              {
                ...
              }
              else
                throw ...
            }
          }
        }
        case '\':
        {
          ...
        }
        default:
        {
        {
          switch(*++pch)
          {
            case 'i':
            case 'd':
            {
              if(params[index].type() == typeid(int) ||
                 params[index].type() == typeid(short))
              {
                ...
              }
              else
                throw ...
            }
          }
        }
        case '\':
        {
          ...
        }
        default:
        {
          putchar(*pch);
        }
      }
    }
  }

附:boost::any.hpp
#ifndef BOOST_ANY_INCLUDED
#define BOOST_ANY_INCLUDED

// what:  variant type boost::any
// who:   contributed by Kevlin Henney,
//        with features contributed and bugs found by
//        Ed Brey, Mark Rodgers, Peter Dimov, and James Curran
// when:  July 2001
// where: tested with BCC 5.5, MSVC 6.0, and g++ 2.95

#include <algorithm>
#include <typeinfo>

#include "boost/config.hpp"

        ~any()
        {
            delete content;
        }

    public: // modifiers

        any & swap(any & rhs)
        {
            std::swap(content, rhs.content);
            return *this;
        }

        template<typename ValueType>
        any & operator=(const ValueType & rhs)
        {
            any(rhs).swap(*this);
            return *this;
        }

        any & operator=(const any & rhs)
        {
        ~any()
        {
            delete content;
        }

    public: // modifiers

        any & swap(any & rhs)
        {
            std::swap(content, rhs.content);
            return *this;
        }

        template<typename ValueType>
        any & operator=(const ValueType & rhs)
        {
            any(rhs).swap(*this);
            return *this;
        }

        any & operator=(const any & rhs)
        {
            any(rhs).swap(*this);
            return *this;
        }

    public: // queries

        bool empty() const
        {
            return !content;
        }

        const std::type_info & type() const
        {
            return content ? content->type() : typeid(void);
        }

#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
    private: // types
#else
    public: // types (public so any_cast can be non-friend)
#endif

            any(rhs).swap(*this);
            return *this;
        }

    public: // queries

        bool empty() const
        {
            return !content;
        }

        const std::type_info & type() const
        {
            return content ? content->type() : typeid(void);
        }

#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
    private: // types
#else
    public: // types (public so any_cast can be non-friend)
#endif

            holder(const ValueType & value)
              : held(value)
            {
            }

        public: // queries

            virtual const std::type_info & type() const
            {
                return typeid(ValueType);
            }

            virtual placeholder * clone() const
            {

                return new holder(held);
            }

        public: // representation

            ValueType held;

            holder(const ValueType & value)
              : held(value)
            {
            }

        public: // queries

            virtual const std::type_info & type() const
            {
                return typeid(ValueType);
            }

            virtual placeholder * clone() const
            {

                return new holder(held);
            }

        public: // representation

            ValueType held;

        virtual const char * what() const throw()
        {
            return "boost::bad_any_cast: "
                   "failed conversion using boost::any_cast";
        }
    };

    template<typename ValueType>
    ValueType * any_cast(any * operand)
    {
        return operand && operand->type() == typeid(ValueType)
                    ? &static_cast<any::holder<ValueType> *>(operand->content)->held
                    : 0;
    }

    template<typename ValueType>
    const ValueType * any_cast(const any * operand)
    {
        return any_cast<ValueType>(const_cast<any *>(operand));
    }

    template<typename ValueType>

// Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved.
//
// Permission to use, copy, modify, and distribute this software for any
// purpose is hereby granted without fee, provided that this copyright and
// permissions notice appear in all copies and derivatives.
//
// This software is provided "as is" without express or implied warranty.

#endif

--
 .  生命的意义在于   /\   ____\ /\_ \   /\_\                             .                                             
 .      希望         \ \  \___/_\/\ \   \/_/__     __    _ _★           .                                             
 .      工作          \ \   ____\\ \ \    /\  \  /'__`\ /\`'_\           .                                             
 .    爱你的人         \ \  \___/ \ \ \___\ \  \/\  __//\ \ \/           .                                             
 .   和你爱的人         \ \___\    \ \_____\ \__\ \____\ \ \_\           .                                             
 .      ……             \/___/     \/_____/\/__/\/____/  \/_/ @126.com  .                                             


※ 修改:·flier 於 May 13 12:03:25 修改本文·[FROM:  202.114.32.217]                                                   
※ 来源:·BBS 水木清华站 bbs.edu.cn·[FROM: 202.114.32.217]                                                            

本文地址:http://com.8s8s.com/it/it29562.htm