2015-12-03 19 views
5

E 'permitable progettare std::optional (attualmente std::experimental::optional) in modo tale, che, per impostazione predefinita banalmente tipo costruibile T corrispondente std::optional<T> è anche costruibile banalmente di default?banalmente predefinito std :: costruibile opzionale e std :: variante

La stessa domanda riguar da std::variant e il suo discriminatore integrale.

La mia risposta è: "No, non può essere progettato in questo modo, perché il valore del suo discriminatore integrale ottenuto durante l'inizializzazione predefinita sarà indeterminato se l'oggetto ha durata di archiviazione automatica o se è reinterpret_cast -ed da non- archiviazione inizializzata a zero. " La necessità che l'utente esegua l'inizializzazione del valore ogni volta non è consentita.

+0

Posso chiederti in cambio perché è importante per te? Posso immaginare il motivo per cui potresti essere facoltativo essere banalmente copiato. Ma perché banalmente-predefinito-costruibile? Cosa ti compra? – Andrzej

+0

@Andrzej Il contenitore (come 'opzionale' o' variant') dovrebbe essere il più generico possibile, non è vero? Cerco di progettare ['variant' per constexpr] (http://codereview.stackexchange.com/questions/112218/trivial-full-fledged-variant-for-constexpr-proof-of-concept). E attualmente ha abilità superiori. Ma penso "forse dovrei negarlo?". – Orient

+0

@Andrzej Alla fine ho trovato un "bug" nella mia 'variante '. Gli oggetti inizializzati di default hanno un comportamento diverso in fase di compilazione (constexpr) e runtime. Poi ho letto di [intiializations] (http://en.cppreference.com/w/cpp/language/initialization). E ho scoperto che esiste UB per usare la 'variante 'intiializzata predefinita nello stack. – Orient

risposta

8

La tua risposta è corretta: non puoi. La specifica richiede che il suo "flag inizializzato" sia impostato su false in base alla costruzione predefinita.

3

Come hai spiegato tu stesso, non puoi implementare std :: facoltativo in questo modo, perché cambieresti la semantica (is_trivially_default_constructible fa parte dell'interfaccia di classe).

Tuttavia, se si richiede questa semantica per qualche motivo nel codice, non vi è alcun motivo, perché non è possibile implementare una classe opzionale molto simile che è banalmente configurabile come predefinita. Quindi, se usato, azzeralo inizializzandolo tramite {} e - se è ciò che vuoi - considera zero come vero nell'operatore bool.