简体   繁体   中英

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

I'm writing some code using std::optional's and am wondering if C++17's 'if statements with initializers' will be able to help unpack values?

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

I'm making up the function Unpack here:

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

But, my question is. Will C++17 'if statement with initializer' help here? If so, how would it be coded?

Update, this is actually mainly an issue when using optional which is extremely easy to misuse because the optional and *optional both return bools and you don't get any compiler warning when somebody trys to access the value and forgets the *.

There is not, and cannot possibly be, such an Unpack() function.

But you could certainly do:

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

though the extra o check is kind of redundant.


This is one of those places where it'd be nice if optional<T> modeled a container of at most one element, so that you could do:

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

but we don't have that interface.

In order for this to work, there has to be a value for the unpacked value if it isn't there.

So

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 } )
}

would do what you wanted.

But as an optional already returns if it is engaged in a bool context you really should just:

if (auto i = get_optional())

then use *i within the body.

...

Now if optional stated that operator* returned a reference, and that return value was defined but accessing it was not defined when it was not engaged, then you could write an Unpack method or function that doesn't require a default value.

As far as I am aware this is not true. And as it doesn't really add anything, I don't see why it should be true.

Maybe this would work:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM