2016-06-21 17 views
7

This page afferma che la funzione make_optional in C++ 17 restituisce un constexpr optional<...>. Penso che (potrei avere torto però) ciò richiederebbe che optional<T> abbia un costruttore di copia o spostamento constexpr. Tuttavia, this page dice anche che non è il caso.C++ 17 make_optional constexpr-ness

Non so come sia possibile implementare make_optional mentre la bozza C++ 1z si trova attualmente. Vedere this post per chiarimenti. C'è qualche soluzione alternativa, o forse è solo l'errore di bozza/cppreference standard?

+0

Non ci sono domande in questa domanda. – immibis

+0

@immibis Aggiornato :) –

+1

cppreference non ha evocato che 'constexpr' dal nulla, sai ... –

risposta

2

Grazie a @Yakk e @ T.C. per le loro spiegazioni. Mi sento un esempio dovrebbe rendere le cose più chiare:

struct wrapper { 
    int value; 

    // non-explicit constexpr constructor 
    constexpr wrapper(int v) noexcept : value(v) {} 

    // non-constexpr copy & move constructors 
    wrapper(const wrapper& that) noexcept : value(that.value) {} 
    wrapper(wrapper&& that) noexcept : value(that.value) {} 
}; 

constexpr wrapper make_wrapper(int v) 
{ 
    return {v}; 
} 

int main() 
{ 
    constexpr auto x = make_wrapper(123); // error! copy/move construction, 
              // but no constexpr copy/move ctor 

    constexpr int y = make_wrapper(123).value; // ok 
    static_assert(y == 123, "");    // passed 
} 

Così make_wrapper fa ritorno con successo un constexpr wrapper; è la costruzione di copia/spostamento (sebbene solitamente elisa dai compilatori) che impedisce la compilazione del codice, poiché non esiste un costruttore di copia/spostamento constexpr.

Possiamo verificare constexpr -ness dell'oggetto restituito (temporaneo) wrapper utilizzando il suo valore membro per inizializzare una variabile constexpr.

1

È possibile costruire direttamente valori di ritorno in C++ 11 con return {something}; Se ci sono cori non espliciti che sono constexpr, è possibile restituirli da una funzione.

+0

Credo che sia un'illusione causata da copia-elisione. Senza copy-elision non verrà compilato: [gcc] (https://godbolt.org/g/X3pTzv), [clang] (https://godbolt.org/g/AiqxxV). –

+0

E come le risposte nel mio post collegato menzionato, anche se il compilatore esegue copy-elision, un costruttore di copia/spostamento 'constexpr' deve essere ancora accessibile (anche se alla fine non viene utilizzato). –

+0

@ZizhengTai È colpa del tuo stesso esempio che sta facendo un'altra copia. https://godbolt.org/g/jT7mHd L'inizializzazione della copia-lista non crea temporaries, concettuali o meno. –

Problemi correlati