tribool:
boost.tribool类似c++内置的bool类型,但基于三态的布尔逻辑:在true和false之外还有一个indeterminate状态(未知,不确定).
#include <boost/logic/tribool.hpp>
using namespace boost;
tribool类内部实现了三态bool值的表示,除了构造函数没有什么其他成员函数,可以再创建tribool对象的同时传入三态bool值对它进行初始化,如果使用无参的缺省构造函数,那么tribool默认值是false。
对tribool的操作都是通过逻辑运算符合比较运算符的重载来完成的,支持的逻辑运算包括||,&&和!,比较运算支持==和 !=,这些操作都可以任意混合bool和tribool一起运算.
不确定状态indeterminate时一个特殊的tribool值,它与bool值true,false的运算遵循三态布尔逻辑:
【1】任何与indeterminate的比较操作结果都是indeterminate;
【2】与indeterminate的逻辑或运算(||)只有与true运算结果为true,其他均为indeterminate;
【3】与indeterminate的逻辑与运算(&&)只有与false运算结果为false,其他均为indeterminate;
【4】indeterminate的逻辑非操作(!)结果仍为indeterminate。
自由函数indeterminate()可以判断一个tribool是否处于不确定状态.
用法:
tribool如果使用true和false两个值,那么tribool与bool的用法完全相同,但如果需要使用indeterminate值,就必须遵循三态布尔的逻辑运算规则。
示例:
#include <iostream>
#include <assert.h>
#include <boost/logic/tribool.hpp>
using namespace boost;
using namespace std;
int main()
{
tribool tb(true);
tribool tb2(!tb);
if (tb)
{cout<<"true"<<endl;}
tb2 = indeterminate; //tb2是不确定状态
assert(indeterminate(tb2)); //用indeterminate函数检测状态
cout<< tb2 <<endl;
if (tb2 == indeterminate)
{ cout<< "indeterminate"<<endl; }
cout<< (tb2 || true) <<endl;
cout<< (tb2 && false) <<endl;
system("pause");
return 0;
}
在处理tribool的不确定状态时必须要小心,因为它既不是true也不是false,使用它进行条件判断永远都不会成立,判断不确定状态必须与indeterminate值比较或者使用indeterminate()函数
tribool tb(indeterminate);
if (tb) //永远不成立
cout<<"never reach here"<<endl;
if (!tb) //永远不成立
cout<<"never reach here"<<endl;
if (indeterminate(tb))
cout<<"indeterminate"<<endl;
为第三态更名:
只需要在全局内使用宏BOOST_TRIBOOL_THIRD_STATE就可以为第三太更名:
BOOST_TRIBOOL_THIRD_STATE(unknown)
然后就可以随意使用这个新名字代替原来的indeterminate:
tribool tb(unknown);
assert(unknown(tb));
assert(unknown(tb || false));
改名原理:
tribool默认的第三太indeterminate不是一个真正的类型值(typedef或者enum),而是一个函数,它被用来判断tribool对象内部值是否是第三太,宏BOOST_TRIBOOL_THIRD_STATE只是定义了一个新的等价函数而已,类似:
inline bool some_name(tribool x)
{return x.value == tribool::indeterimnate_value;}
因为宏BOOST_TRIBOOL_THIRD_STATE实质上定义了一个函数,而c++不允许函数嵌套,所以这个宏最好在全局域使用,它将在定义后的整个源代码中生效。
如果把BOOST_TRIBOOL_THIRD_STATE用在一个名字空间里,那么新的第三太名字将成为名字空间的一个成员,使用时需加上名字空间限定:
namespace tmp_ns
{BOOST_TRIBOOL_THIRD_STARE(unknown)};
tribool tb(tmp_ns::unknown);
输入输出:
tribool可以如bool类型一样进行流操作,但需要包含另外一个头文件<boost/logic/tribool_io.hpp>
只要包含这个文件,就可以使用>>,<<操作符向cin,cout等流对象输入输出,false,true和indeterminate分别对应整数0,1,2,如果设置了流的boolalpha标志,则对应"false","true","indeterminate".
示例:
#include <iostream>
#include <assert.h>
#include <boost/logic/tribool.hpp>
#include <boost/logic/tribool_io.hpp>
using namespace boost;
using namespace std;
int main()
{
tribool tb1(true),tb2(false),tb3(indeterminate);
cout << tb1<<","<<tb2<<","<<tb3<<endl;
system("pause");
return 0;
}
与optional<bool>的区别:
optional<bool>的语义是未初始化的bool,是无意义的值,而tribool的indeterminate是已经初始化的有意义的值,它表示bool不确定。
此外,使用方法的差别,optional<bool>需要使用类似指针的方式访问容器内的bool值,而tribool可以如普通的bool类型一样直接使用,并且支持各种逻辑运算。
选择optional<bool>还是tribool需要由代码的具体需求来决定,如果返回值可能是无效的(不存在有效的返回值),那么就是optional<bool>,如果返回值总是确定的,但可能无法确定其意义,那么就用tribool。