boost 库实用工具之optional
1. optional
在实际的开发中,我们经常会遇到“无效值”的情况,例如函数并不是总能返回有效值,很多时候正确的执行了却不是合理的值,就好比数学中的解释,结果不在有效范围内。这时候我们就需要一个“容器”包装“可能产生无效值”的对象。
optional 使用“容器”的语义,包装了“可能产生无效值”的对象,实现了“未初始化”的概念。
optional 位于boost命名空间中,
template<class T>
class optional
{
pulic:
optional(); /// 构造函数
optional(none_t);
optional(T const& v);
optional(bool condition, T v);
optional& operator= (T const &rts);
template<class...Args>
void emplace(Args...&&args); /// 就地创建
///重载操作符
T* operator ->();
T& operator *();
///访问值
T& get();
T& get_ptr();
T& value(); /// 访问值,可能抛出异常
T const& value_or(T const& default) const;
template<typename E>
T value_or_eval(F f) const;
explicit operator bool()const; /// 显示bool 转型
bool operator !() const; /// 判断
}
optional 的真实接口很复杂,因为它要能够包装任何的类型,但实际的接口还是比较简单的。
optional 操作用法
#pragma once
#include <type_traits>
#include "std.hpp"
using namespace std;
#define BOOST_DISABLE_ASSERTS
#include <boost\optional.hpp>
using namespace boost;
///
void case1()
{
cout << typeid(none).name() << endl;
cout << std::is_member_object_pointer<none_t>::value << endl;
}
void case2()
{
/// 构造一个optional 对象
boost::optional<int> op0; /// 未初始化的optional对象
boost::optional<int> op1(none); /// 同上,使用none赋予未初始化值
assert(!op0); /// bool 测试
assert(op0 == op1); /// 比较两个optional 对象
assert(op1.value_or(253) == 253); /// 使用缺省值
std::cout << op1.value_or_eval( /// 使用函数对象
[]() {return 874; }) << endl; /// 使用lambda函数对象
optional<string> ops("test"); /// 初始化为字符串对象
cout << *ops << endl;
ops.emplace("monado", 3); /// 就地创建一个字符串,没有拷贝对象,只是用前3个字符
assert(*ops == "mon");
vector<int> v(10);
boost::optional<vector<int>&> opv(v); /// 创建一个optional对项,容纳一个容器的引用
assert(opv);
opv->push_back(5); /// 操作容器
assert(opv->size() == 11);
opv = none; /// 置为未初始化状态
assert(!opv); /// 此时为无效值
}
/// optional 作为函数的返回值
boost::optional<double> calc(int x) /// 求倒数
{
return boost::optional<double>(x != 0, 1.0 / x); /// 条件构造函数
}
boost::optional<double> sqrt_op(double x) /// 计算实数的平方根
{
return optional<double>(x > 0, sqrt(x));
}
void case3()
{
optional<double> d = calc(10);
if (d) /// 调用 optional bool() 测试d 的有效性
{
cout << *d << endl;
cout << d.value() << endl;
}
d = sqrt_op(-10);
if (!d)
cout << "no result " << endl;
}
void case4()
{
/// 创建形 构造器,工厂函数
auto x = make_optional(5); /// auto 自动推导类型
assert(*x == 5);
auto y = make_optional<double>((*x > 10), 1.0);
assert(!y);
}
void test_optional()
{
case1();
case2();
case3();
case4();
}