Search code examples
c++option-typeconstexprplacement-newc++17

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


Solution

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