7

我正在使用 std::optional 编写一些代码,并且想知道 C++17 的“带有初始化程序的 if 语句”是否能够帮助解包值?

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 都返回布尔值,并且当有人尝试访问该值并忘记 *.

4

3 回答 3

6

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

但你当然可以这样做:

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

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


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

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

但我们没有那个接口。

于 2016-09-20T16:24:25.143 回答
2

为了使其工作,如果未打包的值不存在,则必须有一个值。

所以

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如果它在bool上下文中已经返回,你真的应该:

if (auto i = get_optional())

然后*i在体内使用。

...

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

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

于 2016-09-20T17:30:09.610 回答
-1

也许这会起作用:

auto optValue = getOptional();
if (auto value = *optValue; optValue) { ...use value here... }
于 2019-04-22T15:23:30.713 回答