为什么 boost::optional::is_initialized() 被弃用了?

Why is boost::optional::is_initialized() deprecated?

本文关键字:initialized optional boost is 为什么      更新时间:2023-10-16

我今天注意到boost::optional::is_initialized()在 Boost 1.64.0 参考中被标记为已弃用。 我的项目大量撒上is_initialized()以检查boost::optional是否包含值。

我没有看到任何其他方法可以正确测试boost::optional是否已初始化,我错过了什么吗?

boost::optional有一个explicit operator bool(),这意味着如果fooboost::optional,我可以做if(foo){...}。 但是,如果fooboost::optional<bool>或其他boost::optional<T>T可转换为bool,这将给出错误的结果。

Boost希望用户做什么?

但是,如果 foo 是 boost::optional 或其他一些 boost::optional,其中 T 可转换为 bool 时,这将给出错误的结果。

否,因为没有到基础类型的隐式转换。可选项的"真实性"¹始终指其初始化状态。

您可能唯一一次得到隐式转换发生的印象是在关系运算符中。但是,这不是对基础类型进行隐式转换,而是显式提升运算符。

¹ 我的意思是上下文(显式)布尔转换

更新

事实上,对于boost::optional<bool>来说,在 c++11 之前的模式中有一个警告:

其次,虽然是可选的<>在 C++11 中提供了到 bool 的上下文转换,但这回退到旧编译器上的隐式转换

在这种情况下,显然最好明确地与boost::none进行比较。

在撰写本文时,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)相同。

旁白:有点奇怪的是,is_initialized被弃用了,然后又添加了一个具有不同名称的完全相同的函数。我怀疑这是为了与 C++17 的 std::optional 兼容。

对于将来的参考,如 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){}