boost::any

原创 2002年08月02日 09:23:00

发信人: 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]                                                            

boost::any库的使用

boost::any库的用法 最近尝试用boost库,作为另一代的C++标准,boost库确实很优秀。 boost::any可以存放任何类型的C++类型,也可以是用户自定义的类型。非常方便,可以很...
  • chenzulong198867
  • chenzulong198867
  • 2012年12月13日 15:46
  • 5746

boost::any的使用和扩展

前言 boost::any类为我们提供了一个十分强大的功能:只要定义一个any对象,就可以保存任意类型的数据到这个对象中,而且还可以动态改变类型。这比我么在COM中使用到的VARIANT结构要强...
  • mfcing
  • mfcing
  • 2015年03月28日 21:12
  • 3775

boost.any源码整理和使用说明

Source#include #include  #include "boost/config.hpp"#include #include #include #include  namespace k...
  • laibach0304
  • laibach0304
  • 2007年08月24日 22:44
  • 562

boost::any实现分析

这里提到的boost::any,下面来分析一下boost::any的实现。 class any { public: // structors any() ...
  • zp373860147
  • zp373860147
  • 2013年03月19日 17:09
  • 2389

boost::any基本用法

boost::any的基本用法
  • morning_color
  • morning_color
  • 2015年09月23日 15:37
  • 1409

Boost中的容器boost::any

导言 Boost.any的特性 – 能够保存任意类型的变量,这和STL有很大的不同; – 模拟动态类型; – 类型安全:不对存入any的变量进行类型强制转换; – 异常安全; – 可写出动态...
  • iFuMI
  • iFuMI
  • 2016年06月12日 14:12
  • 443

boost::any类型实现原理

boost::any是一种通用类型,可以存放任意值。 问题:通用类型any如何存放任意值? A: 这里的通用类型类似于脚本语言中的类型。 方案一, union结构体:但union只能存放固定种类的值,...
  • u012702526
  • u012702526
  • 2014年04月03日 21:20
  • 1359

boost::any 使用注意问题

boost::any 使用注意问题 flyfish   编译环境  VC2010 看如下代码 void function(boost::any T) { try { BYT...
  • flyfish1986
  • flyfish1986
  • 2015年01月06日 13:47
  • 1680

boost.any实现任意类型存储

当你需要一个可变的类型时,有三种可能的解决方案: 无限制的类型,如 void*. 这种方法不可能是类型安全的,应该象逃避灾难一样避免它。可变的类型,即支持多种类型的存储和获取的类型。支持转换的类型,...
  • IT_PCode
  • IT_PCode
  • 2015年01月16日 11:23
  • 1435

Linux C++ Boost::any深入理解

/*  * any_test.cpp  *  *  Created on: 2014年5月2日  *      Author: ***  */ #include #include #include ...
  • shuyun123456789
  • shuyun123456789
  • 2014年05月01日 19:16
  • 932
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:boost::any
举报原因:
原因补充:

(最多只允许输入30个字)