为什么 boost::optional::is_initialized() 被弃用了?
Why is boost::optional::is_initialized() deprecated?
我今天注意到boost::optional::is_initialized()
在 Boost 1.64.0 参考中被标记为已弃用。 我的项目大量撒上is_initialized()
以检查boost::optional
是否包含值。
我没有看到任何其他方法可以正确测试boost::optional
是否已初始化,我错过了什么吗?
boost::optional
有一个explicit operator bool()
,这意味着如果foo
是boost::optional
,我可以做if(foo){...}
。 但是,如果foo
是boost::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){}
- 为什么 std::optional::operator=(U&&) 要求你是非标量类型?
- 带有 -stdlib=libc++ 的 clang++ 9.0.1 找不到<optional>
- 检查某些类型是否是模板类 std::optional 的实例化
- 在C++中,使用带有 std::optional 参数的函数<T>来表示可选参数是否有意义?
- boost 是否有按特殊类型值编码状态"compact optional"?
- 使用 std::optional,而不是自己的结构
- 如何解决"no Qt platform plugin could be initialized"问题?
- C++17:使用 std::optional 来评估枚举是否包含值
- 从返回 std::optional of std::vector 的函数中获取结果到调用方
- C++ 错误:"array must be initialized with a brace-enclosed initializer"
- API 返回智能指针的 std::optional 以明确指定指针可能为 null 是否有意义?
- 函数可以应用于 std::optional,并返回一个可选值吗?
- 为什么 std::optional::value_or 没有默认 ctor 类型的专用化?
- 使用std::optional时的命名返回值优化
- std::function<std::optional<T>()> 如何与返回 T 的 lambda 兼容?
- 如何正确地将 boost::optional<std::chrono::d uration> 作为函数参数?
- 如何从 std::optional 中获取 QByteArray<QByteArray>,并在没有其他 malloc 的情况下保留 std::nullopt?
- 为什么返回std::optional有时移动,有时复制
- 为什么 std::optional 的强制转换运算符被忽略了
- 使用 std::experimental::optional,给出编译错误