我正在使用std::optional编写一些代码,我想知道C++17的"if语句和初始化程序"是否能够帮助解包值?
std::optional<int> optionalInt = GetOptionalInt();
我正在制作函数Unpack here:
if( auto [value, has_value] = optionalInt.Unpack(); has_value )
{
// Use value here.
}
但是,我的问题是。C++17的if语句和初始值设定项在这里有帮助吗?如果是,它将如何编码?
更新,这实际上主要是使用optional时的一个问题,它非常容易被滥用,因为optional和*optional都返回bools,当有人试图访问该值并忘记*时,你不会得到任何编译器警告。
没有也不可能有这样的Unpack()
函数。
但你当然可以:
if (std::optional<int> o = GetOptionalInt(); o) {
// use *o here
}
尽管额外的CCD_ 2检查有点多余。
如果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
已经返回,如果它参与了bool
上下文,那么你真的应该只:
if (auto i = get_optional())
然后在体内使用CCD_ 6。
现在,如果optional
声明operator*
返回了一个引用,并且该返回值被定义为,但在未参与时访问它没有被定义,那么您可以编写一个不需要默认值的Unpack
方法或函数。
据我所知,这不是真的。由于它并没有真正增加任何内容,我不明白为什么它应该是真的。
也许这会奏效:
auto optValue = getOptional();
if (auto value = *optValue; optValue) { ...use value here... }