在 C++17 中,是否可以使用带有初始值设定项的 if 语句来解包可选?

In C++17 can an if statement with an initializer be used to unpack an optional?

我正在使用 std::optional 编写一些代码,我想知道 C++17 的 'if statements with initializers' 是否能够帮助解包值?

std::optional<int> optionalInt = GetOptionalInt();

我正在这里编写函数 Unpack:

if( auto [value, has_value] = optionalInt.Unpack(); has_value )
{
    // Use value here.
}

但是,我的问题是。 C++17 'if statement with initializer' 会在这里提供帮助吗?如果是这样,它将如何编码?

更新,这实际上主要是使用 optional 时的一个问题,它非常容易被滥用,因为 optional 和 *optional 都是 return bools,当有人试图访问时你不会得到任何编译器警告值并忘记 *.

没有,也不可能有这样的 Unpack() 功能。

但你当然可以:

if (std::optional<int> o = GetOptionalInt(); o) {
    // use *o here
}

尽管额外的 o 检查有点多余。


如果 optional<T> 对最多包含一个元素的容器建模,那么这是其中一个很好的地方,这样您就可以:

for (int value : GetOptionalInt()) {
    // possibly not entered
}

但是我们没有那个界面。

为了使其工作,如果不存在,则必须有一个解压缩值的值。

所以

template<class T, class U>
std::pair< T, bool > unpack_value( std::optional<T> const& o, U&& u ) {
  return { o.value_or(std::forward<U>(u)), (bool)o } )
}

会做你想做的。

但是作为一个 optional 已经 return 如果它处于 bool 环境中,你真的应该:

if (auto i = get_optional())

然后在正文中使用*i

...

现在,如果 optional 声明 operator* return 编辑了一个引用,并且 return 值已定义 但未定义访问它 当它没有被使用时,那么你可以写一个 Unpack 不需要默认值的方法或函数。

据我所知,这不是真的。因为它并没有真正添加任何东西,所以我不明白为什么它应该是真的。

也许这行得通:

auto optValue = getOptional();
if (auto value = *optValue; optValue) { ...use value here... }