在C++中,有没有一个不那么冗长的习惯用法来拆包可选项

Is there a less verbose idiom for unpacking an optional in C++?

本文关键字:习惯 惯用法 可选项 C++ 有一个      更新时间:2024-09-21

在我目前正在进行的项目中,我发现自己写了很多代码,如下所示,其中,get_optional_foo返回一个std::optional:

//...
auto maybe_foo = get_optional_foo(quux, ...)
if (!maybe_foo.has_value())
return {};
auto foo = maybe_foo.value()
//...
// continue on, doing things with foo...

如果我得到一个空选项,我想退出函数;否则,我想为该值分配一个非可选变量。我已经开始使用用maybe_前缀命名可选项的约定,但我想知道是否有某种方法可以做到这一点,这样我根本不需要为可选项使用临时名称?这个变量只用于检查null选项,如果有值,则取消引用。

您不需要中间对象。std::optional支持一个指针接口来访问它,所以你可以像一样使用它

//...
auto foo = get_optional_foo(quux, ...)
if (!foo)
return {};
//...
foo->some_member;
(*foo).some_member;

与您的要求略有不同,但请考虑:

if (auto foo = get_optional_foo(1)) {
// ...
return foo->x;
} else {
return {};
}

这将函数的主体放在if()块中,该块可能更可读。

我能想到的最短的:

auto maybe_foo = get_optional_foo(quux, ...)
if (!maybe_foo) return {};
auto &foo = *maybe_foo; // alternatively, use `*maybe_foo` below

如果函数中有多个选项,而且它们不太可能是空的,那么可以用try - catch来包装整个函数。

try {
auto &foo = get_optional_foo(quux, ...).value();
auto &bar = get_optional_bar(...).value();
...
} catch (std::bad_optional_access &e) {
return {};
}