在 C++ 中解包可选是否有更简洁的习惯用法?
Is there a less verbose idiom for unpacking an optional in C++?
在我目前正在从事的项目中,我发现自己编写了很多如下所示的代码,其中,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_
前缀命名可选的约定,但我想知道是否有某种方法可以做到这一点,这样我根本不需要为可选使用临时的?此变量只会用于检查空选项并在有值时取消引用。
我能想到的最短的:
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 {};
}
您不需要中间对象。 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()
块中,这可能更具可读性。
在我目前正在从事的项目中,我发现自己编写了很多如下所示的代码,其中,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_
前缀命名可选的约定,但我想知道是否有某种方法可以做到这一点,这样我根本不需要为可选使用临时的?此变量只会用于检查空选项并在有值时取消引用。
我能想到的最短的:
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 {};
}
您不需要中间对象。 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()
块中,这可能更具可读性。