ITPub博客

首页 > 应用开发 > IT综合 > boost::any (转)

boost::any (转)

原创 IT综合 作者:worldblog 时间:2007-12-12 14:33:47 0 删除 编辑
boost::any (转)[@more@]

发信人: 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(str) << endl;
  }
  catch(boost::bad_any_cast e)
  {
  cerr << e.what() << endl;
  }


  在应用方面,any类型适合于类型不同但使用相关的值。如C++的...
形式的函数参数本事不是类型安全的,可以通过vector改造之
然后在使用时检测类型是否匹配,如可改造printf为
  void safe_printf(const char *format, const vector& 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
#include

#include "boost/config.hpp"

  ~any()
  {
  delete content;
  }

  public: // modifiers

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

  template
  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
  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
  ValueType * any_cast(any * operand)
  {
  return operand && operand->type() == typeid(ValueType)
  ? &static_cast *>(operand->content)->held
  : 0;
  }

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

  template

// 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] 


来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/10752043/viewspace-992165/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
  • 博文量
    6241
  • 访问量
    2405695