Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std::experimental::optional<T> implementation: Constexpr constructor confusion

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

like image 735
nshct Avatar asked Mar 08 '16 06:03

nshct


1 Answers

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

like image 173
Luc Danton Avatar answered Oct 25 '22 13:10

Luc Danton