2016-03-08 14 views
5

Während Umsetzungstd::experimental::optional (cppreference.com) Ich habe durch die Angabe eines bestimmten Konstruktor verwechselt, nämlich:std :: Versuchs :: optional <T> Implementierung: constexpr Konstruktor Verwirrung

constexpr optional(const T& value); // (4) 

(Source)

Dieser Konstruktor erlaubt optional<T>, für einen trivial zerstörbaren Typ T, in constexpr Kontext konstruiert werden. Während die erste Anforderung, nämlich das Ausschalten des vom Benutzer bereitgestellten Destruktors in diesem Fall optional<T> ein Literal-Typ zu machen, einfach zu lösen ist, weiß ich nicht, wie man die Begrenzung von umgehen kann, die in consstexpr nicht erlaubt ist .

Ich dachte, ich sollte optional<T> mit 10 implementieren, um Typen T, die nicht standardmäßig konstruierbar sind und alle Ausrichtungsanforderungen erfüllen, falls zutreffend. Aber wie gesagt, constexpr verbietet mir die Verwendung von Placement neu in diesem bestimmten Konstruktor.

Hatte ich zu viel Kaffee und sehe hier keine offensichtliche Lösung?

Danke

+0

Mögliche Duplikate von [Wie sollte man std :: optional verwenden?] (Http://stackoverflow.com/questions/16860960/how-should-one- use-stdoptional) – Matriac

+2

@Matriac das ist eine Frage über die Implementierungsseite. – nshct

+1

Eine "Union" könnte für diesen speziellen Konstruktor funktionieren, aber ich bin nicht sicher, dass es ausreicht, alle Fälle zu behandeln. – hvd

Antwort

4

Ich weiß nicht, wie um die Begrenzung der Platzierung neuer bekommt nicht in constexpr darf.

Das ist eine korrekte Diagnose, wörtliche Typen, constexpr und neue Ausdrücke mischen nicht. Der einfachste Weg, die verschiedenen Anforderungen von std::experimental::optional<T> zu erfüllen, ist die Implementierung mit varianten Mitgliedern. Einfach ausgedrückt, muss ein union irgendwann beteiligt sein. Eine schnelle Skizze:

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

Als der Tat verwendet die alte Serie von optional Vorschläge have a paragraph on the technique zu zeigen, dass die Anforderungen es her vernünftig waren überhaupt stellen. (Heutzutage lebt std::experimental::optional in den verschiedenen Library Fundamentals Candidate TSs weiter.)

+0

Danke. Ich weiß nicht, warum ich mich so sehr auf aligned_storage konzentriert habe, aber das ist die richtige Lösung. – nshct

Verwandte Themen