How to disengage std::experimental::optional?

2019-05-01 06:17发布

问题:

With Boost I can create an optional in-place with:

boost::optional<boost::asio::io_service::work> work = boost::in_place(boost::ref(io_service));

And disengage it with:

work = boost::none;

With C++14 / experimental support, I can instead construct an optional in-place with:

std::experimental::optional<boost::asio::io_service::work> work;
work.emplace(boost::asio::io_service::work(io_service));

But I'm at a loss for how to disengage it...

回答1:

work = std::experimental::nullopt;

should disengage work.
The library fundamental TS specifies in [optional.nullopt]:

The struct nullopt_t is an empty structure type used as a unique type to indicate a disengaged state for optional objects.

There is an appropriate assignment operator, [optional.object.assign]:

optional<T>& operator=(nullopt_t) noexcept;

Effects: If *this is engaged calls val->T::~T() to destroy the contained value; otherwise no effect.

To avoid constructing a nullopt_t object every time, a constant of this type is already declared:

struct nullopt_t{see below};
constexpr nullopt_t nullopt(unspecified);



回答2:

This simplest way to disengage an optional is with foo = {};, which is resolved as move assignment from a disengaged prvalue optional. The specification actually goes out of its way to enable this syntax which would otherwise be ambiguous with assignment from the contained type. (See [optional.object.assign] para 18-23 in N4023 for details)



回答3:

Having read through the headers, the correct way to disengage the std::experimental::optional appears to be:

work = std::experimental::nullopt;