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...
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);
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)
Having read through the headers, the correct way to disengage the std::experimental::optional appears to be:
work = std::experimental::nullopt;