4.7.5 与optional<bool>的区别
optional<bool>在功能上有些类似tribool,一个未初始化的optional<bool>同样可以表示不确定的bool值,例如:
- optional<bool> b;
- if (!b) //b未初始化,既不是true也不是false
- { cout << "indeterminate" << endl; }
- b = false;
- if (b) //b有值false
- { cout << "b=" << *b << endl; }
但optional<bool>的语义是未初始化的bool,是无意义的值,而tribool的indeterminate是已经初始化的有意义值,它表示bool值不确定。这两者存在着细微但十分重要的差别。
此外,两者的使用方法也存在差别。optional<bool>需要使用类似指针的方式访问容器内的bool值,而tribool可以如普通的bool类型一样直接使用,并且支持各种逻辑运算。
由于optional存在一个隐式bool转换,用于检测optional是否已经初始化,因此在bool语境下如果不注意optional的这个特性很容易导致意外的错误。例如,下面的代码本意是想使用optional内的bool值作为if语句的判断条件,但实际上条件判断的是optional未初始化:
- optional<bool> b(false);
- if (!b) //optional的隐式bool转换
- { cout << "false" << endl; }
- 正确的写法应该是:
- if (b && !*b) //b已经初始化且值为false
- { cout << "false" << endl; }
选择optional还是tribool需要由代码的具体需求来决定。如果返回值可能是无效的(不存在有效的返回值),那么就是optional;如果返回值总是确定的,但可能无法确定其意义,那么就用tribool。