Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to disengage std::experimental::optional?

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...

like image 312
Riot Avatar asked Nov 12 '14 21:11

Riot


3 Answers

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

like image 122
Columbo Avatar answered Nov 01 '22 04:11

Columbo


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)

like image 3
Casey Avatar answered Nov 01 '22 05:11

Casey


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

work = std::experimental::nullopt;
like image 1
Riot Avatar answered Nov 01 '22 05:11

Riot