在 Javascript 中,如果我有一个潜在的 null 对象
obj
,如果不为 null,它将有一个字段 x
,我可以写 obj?.x
。这称为 可选链接或安全导航:如果 obj 不是具有可访问字段的对象,则不会抛出异常(如果 obj
是一个对象但没有 x
字段,则不会抛出异常,尽管这是也许是一个单独的功能)。
现在让我们转向 C++,从 C++17 开始它就有了标准库
std::optional<T>
。假设我们有:
struct Foo { Bar x; }
我有一个名为
optional<Foo>
的 obj
对象。天真地,我可能会写出这样的表达式:
obj ? obj->x : optional<Bar>{}
...但这行不通,因为两个结果表达式的类型不同,并且三元运算符不能协调它们。 Godbolt 确认,使用以下代码:
#include <optional>
using Bar = int;
struct Foo { Bar x; };
std::optional<Bar> f()
{
std::optional<Foo> obj {};
return obj ? obj->x : std::nullopt;
}
那么,在 C++ 中,有什么简短的惯用法来表达
obj?.x
呢?
注意:任何语言标准版本都可以,但显然越旧越好。
C++23 引入了 可选的 Monadic 操作,因此您可以使用 std::Optional::transform
#include <optional>
using Bar = int;
struct Foo { Bar x; };
std::optional<Bar> f()
{
std::optional<Foo> obj {};
return obj.transform([](auto&& obj) { return obj.x;});
}
对于较低的 C++ 版本,您可以使用 C++11 可选库,它具有类似的操作(地图)