While implementing std::experimental::optional
(cppreference.com) I got confused by the specification of a specific constructor, namely:
constexpr optional( const T& value ); // (4)
(Source)
This constructor allows optional<T>
, for a trivially destructible type T
, to be constructed in constexpr
context. While the first requirement, namely switching off the user-provided destructor in this case to make optional<T>
a literal type, is straight forward to solve, I do not know how to get around the limitation of placement-new not being allowed in constexpr.
I thought I was supposed to implement optional<T>
using std::aligned_storage<T>
to allow types T
that are not default constructible and satisfy any alignment requirements, if applicable. But as I said, constexpr
forbids me from using placement new in that particular constructor.
Did I have to much coffee and am not seeing an obvious solution here?
Thank you
I do not know how to get around the limitation of placement-new not being allowed in constexpr.
That is a correct diagnostic, literal types, constexpr
and new expressions don’t mix. The most straightforward way to fulfil the various requirements of std::experimental::optional<T>
is to implement it with variant members. Put plainly, a union
has to be involved at some point. A quick sketch:
template<typename Val>
struct optional {
union {
Val optional_value;
unsigned char dummy_byte;
};
bool filled;
// post-condition: no-value state
constexpr optional()
: dummy_byte {}
, filled(false)
{}
// post-condition: has-value state
constexpr optional(Val const& val)
: optional_value(val)
, filled(true)
{}
// other special members omitted for brevity
};
Live On Coliru
As a matter of fact, the old series of optional
proposals used to have a paragraph on the technique to demonstrate that the requirements it put forth were reasonable at all. (Nowadays std::experimental::optional
lives on in the various Library Fundamentals candidate TSs.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With