提问人:Bernard 提问时间:5/23/2017 最后编辑:Rakete1111Bernard 更新时间:3/28/2020 访问量:18932
为什么 boost::optional::is_initialized() 被弃用?
Why is boost::optional::is_initialized() deprecated?
问:
我今天注意到它在 Boost 1.64.0 参考中被标记为已弃用。我的项目被大量散布以检查是否包含值。boost::optional::is_initialized()
is_initialized()
boost::optional
我没有看到任何其他方法可以正确测试 a 是否已初始化,我是否遗漏了什么?boost::optional
有一个 ,这意味着我可以做 if 是一个 .但是,如果 是 a 或其他可转换为 的地方,这将给出错误的结果。boost::optional
explicit operator bool()
if(foo){...}
foo
boost::optional
foo
boost::optional<bool>
boost::optional<T>
T
bool
Boost 希望用户做什么?
答:
但是,如果 foo 是 boost::optional 或其他一些 boost::optional,其中 T 可转换为 bool,这将给出错误的结果。
否,因为没有隐式转换为基础类型。可选项的“真实性”¹ 始终是指其初始化状态。
您可能唯一感觉到隐式转换发生的是在关系运算符中。但是,这并不是隐式转换为基础类型,而是显式提升运算符。
¹ 我的意思是上下文(显式)布尔转换
更新
事实上,在 c++11 之前的模式中有一个警告:boost::optional<bool>
其次,尽管 optional<> 在 C++11 中提供了到 bool 的上下文转换,但这又回到了旧编译器上的隐式转换
在这种情况下,显然最好明确地比较 .boost::none
评论
isTrue
-> o && *o
; isFalse
-> o && !*o
; isUndef
-> !o
对于将来的参考,如boost文档所述,从现在开始,您可以像这样进行比较:
boost::optional<int> oN = boost::none;
boost::optional<int> o0 = 0;
boost::optional<int> o1 = 1;
assert(oN != o0);
assert(o1 != oN);
assert(o0 != o1);
assert(oN == oN);
assert(o0 == o0);
您甚至可以执行以下操作:
if(oN != 2){}
或者只是检查是否设置了该值:
if(oN){}
在撰写本文时,Boost 1.72 支持“has_value”方法,该方法尚未弃用。
不过,在引擎盖下,它只是叫“is_initialized”。 查看代码:
bool has_value() const BOOST_NOEXCEPT { return this->is_initialized() ; }
撇开这一点不谈,我见过的另一个方便的技巧是成语。
例如:!!
boost::optional<Foo> x = ...
MY_ASSERT(!!x, "x must be set");
这与写作或更令人望而却步的冗长基本相同。(bool)x
static_cast<bool>(x)
顺便说一句:弃用有点奇怪,后来添加了一个具有不同名称的完全相同的等效函数。我怀疑这是为了与C++ 17的std::optional兼容。is_initialized
评论
has_value()
已添加到 Boost Release 1.68: boost.org/doc/libs/1_68_0/libs/optional/doc/html/boost_optional/....
评论
boost::none
boost::optional<bool>
boost::optional<bool> a
if(a)
*a
a
boost::none