BOOST--any

 
Any 库概述
Any 库可以改进程序:
# 对任意的类型提供类型安全(typesafe)的存储和安全的检索;
# 提供了在标准库容器中存放异构类型(heterogeneous type)的方法
# 传递类型所通过的层无须了解任何该类型的信息.
 
Any 库提供一个类型:any,它允许对任意的类型进行存储,以便稍后进行检索,而且还不损失类型的安全性.很多情况下,我们可能希望在同一个容器中存储互不相关的类型.还有很多情况下,某些特定的代码仅仅关心从一个点到另一个点传递数据的方式,而不关心数据的类型.表面上看,这些事情很容易做.它们可以通过一个诸如void *的无差别类型来实现.同样,它们还可以通过使用一个有差别的联合(discriminated union)来实现.另外,有许多变体类型都通过一些类型标记机制来实现的.然而,所有这些实现方式都缺乏类型安全性,而且只有在最可控的情形下才有可能故意绕过类型系统.标准库的容器对它们所包含的类型进行参数化,因此对这些容器中存储异构类型的元素提出了一个看上去似乎不可能实现的挑战.幸运的是,解决方案不一定必须使用void *,因为Any库允许存储不同类型的对象用于后续的检索.但是还是无法在不了解实际的情况下检索所存储的值,类型安全从而得到保证.
 
Any 库的一个重要特性就是它提供了在标准容器中存储异构类型对象的能力.另外,它还是一种变体数据类型(variant data type).而这正是C++标准库非常需要但又缺乏的数据类型.
 
Any
类any   允许对任意的类型进行类型安全的存储和检索 . 与无差别的类型不同 ,any 类保存了类型的信息 , 而且实际上还不不允许在不知道正确类型的情况下获取所存储的值 . 当然 , 若要查询类型的信息和测试所保存的值的可选项 , 办法还是有的 . 但是最终 , 调用者还是必须知道 any 对象中所存储的值的确切类型 , 否则 any 类就拒绝访问 , any 类来说 , 可以把它看作是一个上了锁的保险箱 , 没有匹配的钥匙 , 就不能进入其中 .any 类对它所存储的类型有以下要求 :
# 可复制构造 (copyConstructible): 它必须可以复制这个类型 .
# 析构函数不抛出异常 : 就象所有的析构函数所应该的那样的 .
# 可赋值 (Assignable): 为了保证异常安全 ( 不符合可赋值要求的类型也可以用于 any , 但没有强异常安全的保证 ).
下面是 any 类的公共接口 :
Namespace boost
{
 Class any {
 Public:
       Any();
       Any(const any &);
       Template<typename ValueType> any (const ValueType&);
       ~any();
       Any & swap(any &);
       Any & operator=(const any &);
       Template<type ValueType&> any & operator=(const ValueType&);
       Bool empty() const;
       Const std::type_info & type() const;
};
}
 
Any(); 该默认构造函数创建一个 any 类的空实例 , 即一个不含有值的 any . 当然 , 也就无法从一个空的 any 类中检索值 , 因为它里面没有值存在 .
Any(const any & other); 该构造函数创建一个已有的 any 对象的独特副本 . 其中 other 中所包含的值被复制并存储到 this .
 Template<typename ValueType> any (const ValueType&); 这个模板化的构造函数存储传递构造函数的类型为 ValueType 的参数的一份副本 . 其中参数是一个 const 引用 , 因此传递一个临时对象以存储到 any 中是合法的 . 注意 , 该构造函数不是显式的 , 那么 any 就回难以使用 , 而且还会影响额外的安全性 .
~any(); 该析构函数销毁 any 类所包含的值 , 但要注意 , 因为裸指针 (raw pointer) 的析构并不会对指针调用运算符 delete 或运算 delete[], 所以在 any 中使用指针时 , 应该把裸指针包装在一个诸如 shared_ptr 的智能指针中 .
 Any &swap(any & other);
交换两个 any 对象中所存储的值 .
Any & operator = (const any & other); any 实例是非空的 , 那么该函数会丢弃所存储的值 , 然后存入 other 值的一份副本 .
Template<type ValueType&> any & operator=(const ValueType&); any 的实例是非空的 , 那么该函数会丢弃所存储的值 , 然后存入 value 的一份副本 , 其中 value 可以是符合 any 要求的任意类型 .
Bool empty() const; 该函数指示当前是否包含值 , 但不用考虑值的类型 . 因此 , any 中存放指针时 , 即使该指针为空 ,empty 函数也要返回 flase.
Const std::type_info & type() const; 该函数指示 any 对象中所存储值的类型 . any 对象为空 , 则该该函数返回的类型为 void.
 
Any 类中的自由函数
Template <typename ValueType> ValueType any_cast(const any& operand);
Any_cast 函数允许访问 any 中所存储的值 . 其参数为要检索其中的值的 any 对象 . 如果类型 ValueType 与所存储的类型不符 , 则抛出一个类型为 bad_any_cast 的异常 . 这里需要注意的是 , 该函数的语法和 dynamic_cast 函数的语法相似 .
 
Template <typename ValueType > const ValueType* any_cast(const any *operand);
Any_cast 函数的重载 , 其参数为 any 对象的指针 , 它返回的是一个指向所存储值的指针 . any 对象中的类型不是 ValueType, 那么该重载将返回一个空指针 . 注意 , 该重载函数的语法仍然和 dynamic_cast 函数的语法相似 .
 
Template <typename ValueType > ValueType* any_cast(any *operand);
Any_cast 函数的另一个重载 , 它与前一个重载版本相似 , 但前一个版本的参数类型和返回类型都使用了 const 限定的指针 , 而这个重载版本则不是这样的 .
 
异常
 Bad_any_cast
当试图将 any 对象转换为该对象所存储类型以外的其他类型时 , 将抛出该异常 .bad_any_cast 异常派生自 std::bad_cast. 需要注意 , 当使用指针参数调用 any_cast 函数时 , 不会抛出异常 ( 类似于使用指针型调用 dynamic_cast 函数返回空指针 ); 但是 , 当使用引用类型调用 any_cast 函数时 , 则在失败时抛出异常 .
 
使用用法
 Any 库定义在命令空间 boost . 我们可以用类 any 来存储值 , 随后用模板函数 any_cast 来检索所存储的值 . 为了使用 any , 程序中需要包含头文件 ”boost/any.cpp”. 创建一个可以存储任意类型的值的实例非常简单 , 如下所示 :
Boost::any a;
对上述实例赋予某个类型的值也很容易 , 如下 :
A = std::string(“A string”);
A = 42;
A = 3.1415;
 Any 类几乎可以接受任何类型的值 . 但是 , 为了真正能使用存储在 any 中的值 , 需要检索它 . 为此 , 需要知道这个值的类型 .
Std::string s = boost::any_cast<std::string> (a);
//throws boost::bad_any_cast
  上述代码不能得到正确结果 , 这是因为对象 a 中当前所包含的值是 double 类型的 , 这时 any_cast 将抛出一个类型为 bad_any_cast 的异常 . 但下面的代码可得到正确的结果 .
Double d = boost::any_cast<double>(a);
 Any 类只有在知道类型的前提下才可以访问它的值 . 一般要牢记 : any 用于存储值 . 而模板函数 any_cast 用于检索存储值 .
 
现有三个类 A,B,C, 它们没有共同的基类 , 想要把它们存储到一个 std::vector .(any 提供了一种更好的解决方法 , 但是它还没有解决对类型的依赖 .)
#include <iostream>
#include <string>
#include <utility>
#include <vector>
#include “boost/any.hpp”
Class A {
Public:
         Void some_function() {std::cout<<”A::somefunction()/n”;}
}
Class B {
Public:
         Void some_function() {std::cout<<”B::somefunction()/n”;}
}
Class C {
Public:
         Void some_function() {std::cout<<”C::somefunction()/n”;}
}
Int main()
{
         Std::cout<<”Example of using any./n”;
         Std::vector<boost::any> store_anything;
         Store_anything.push_back(A());
         Store_anything.push_back(B());
         Store_anything.push_back(C());
         Store_anything.push_back(std::string(“This is fantastic!”));
         Store_anything.push_back(3);
         Store_anything.push_back(std::make_apir(true,7.92));
         Void print_any(boost::any & a);
         //defined later; reports on the value in a
         Std::for_each(store_anything.begin(),store_anything.end(),print_any());
}
 
Void print_any(boost::any & a)
{
         If(A *pA = boost::any_cast<A>(&a))
         {
          pA->some_function();
}
Else if ((B*pB= boost::any_cast<B>(&a))
{
          pB->some_function();
}
Else if ((C*pC= boost::any_cast<C>(&a))
{
          pC->some_function();
}
Else
{
 Try{
 Std::cout<<boost::any_cast<std::string>(a)<<endl;
}
Catch(boost::bad_any_cast&){
 Std::cout<<”error!/n”;
}
}
}
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值