• 容纳非法类型的容器(可以合法)

  • 哨兵角色:NULL,-1,vector::end(),EOF,string::npos

optional解决  有些不存在的哨兵角色

optional  内部保存对象的复制

当模板参数类型为T &  时,保存源对象的引用,与C++内置引用类型不同,可以在声明时不进行初始化,比如  optional<int&>  op;声明op时,其内部的引用成员变量并未初始化

赋值时,转移包装对象,而不是对原包装对象的赋值

常用成员方法:get_value_or , get ,  get_ptr ,  构造  复制  赋值构造,和条件构造 operator *  ->  ,!

View Code
 1 #include<boost/optional.hpp>
 2 //using namespace boost;
 3 //using namespace std;
 4 boost::optional<double> calc(int x)
 5 {
 6     return boost::optional<double>(x!=0,1.0/x);
 7 }
 8 int main()
 9 {
10     boost::optional<int> op;
11     assert(!op);
12     std::cout<<op<<std::endl;
13     calc(0);
14     assert(!op);
15     std::cout<<!op<<std::endl;
16     //assert(op);
17     op=4;
18     std::cout<<op<<std::endl;
19     std::cout<<op.get_value_or(133)<<std::endl;
20     int * p = op.get_ptr();
21     std::cout<<*p<<std::endl;
22 
23 }

 

类比,make_pair()   ,make_shared() ,参数是否为引用类型,待查 

make_optional工厂函数,可根据参数类型自动推导出optional的类型

auto  optional(3)

如果是T &类型的optional对象,make_optional无法自动推导,不能使用make_optional工厂函数

 

一个boost库,in_place_factory  就地创建 ,用于不可拷贝,或复制代价很高的对象

  • any  容纳任意类型的容器(可以为空)

  • any是一个包装类,内部 模板类holder保存传入对象,复制和赋值构造函数是模板函数,这是它能够接受任意类型的原因

any的析构函数  删除 holder对象,如果保存的是指针,不对指针进行delete,会造成内存泄露,需要使用shared_ptr代替

常用成员方法:empty 判空,type 获取类型引用 std::type_info &,swap 交换操作

一个any_cast 友元函数,获取any中包装的对象

any<int> a;
int d= any_cast<int>(a);
string
c; c=any_cast<string>(a);

//改为上面的情况,会抛出异常,即空置或者转换类型和内部包装类型不一致会出现异常,跑出bad_any_cast异常

View Code
1 any<int> a;
2 int b;
3 b=any_cast<int>(a);

注:bad_any_cast是std::bad_cast的子类,经过exception包装,被catch捕获后,可使用boost::exception的所有功能

可以将any_cast进行封装,包含检测异常功能,如封装为get(),get_ptr(),获取其包装对象的引用或者指针

any_cast 使用接受指针参数,返回持有值指针的重载形式,不会抛出异常,返回空指针 

一个简化的工厂函数make_ptr_any,shared_ptr包装原始指针并放入any

any a=make_ptr_any<string>(new string("wang"));//不可使用c字符串,但windows下测试了,编译并不报错

  可以,自己封装函数,使any对象实现 流或字符串输出,补充any自身不能实现流输出的缺陷(无相关成员方法)

未完待续。。。。。。。。。。。。。

 

 

posted on 2013-03-26 19:19  微微来了  阅读(3173)  评论(0编辑  收藏  举报