Lo span può essere constexpr?


11

Tutti i costruttori di std :: span sono dichiarati constexpr, tuttavia non riesco a farli funzionare in un contesto constexpr. Il non commento di una qualsiasi delle seguenti istruzioni comporterà un errore di compilazione.

#include <array>
#include <span>

int main()
{
    constexpr int carray[3] = { 0, 1, 2 };
    constexpr std::array<int, 3> array{ 0, 1, 2 };
    using S = std::span<const int, 3>;

    /*constexpr*/ S span1{ array.data(), 3 };
    /*constexpr*/ S span2{array.begin(), array.end()};
    /*constexpr*/ S span3{carray};
    /*constexpr*/ S span4{array};
}

È infatti possibile creare un tipo di span constexpr, dal momento che sembra che i costruttori non possano mai essere valutati in fase di compilazione quando devono inizializzare un puntatore o un riferimento?


Uncomment i constexprs non li rimuovono.
— Andreas Loanjoe,

Stai inizializzando un intervallo di runtime che intendevo inizializzare un intervallo di tempo di esecuzione
— Andreas Loanjoe

Doh. Non so perché l'ho fatto. nevermind
— NathanOliver,

strano, non vedo perché sarebbe necessario che l'arco di vita viva solo nell'ambito locale ...
— Andreas Loanjoe

Strettamente correlato: stackoverflow.com/q/57545503/2069064
— Barry

Risposte:


13

Non è possibile utilizzare variabili locali con funzione non statica in un'espressione costante del genere. È necessaria la stabilità dell'indirizzo e ciò viene raggiunto solo da oggetti statici. Modifica del codice in

constexpr std::array<int, 3> array{ 0, 1, 2 };
constexpr int carray[3] = { 0, 1, 2 };

int main()
{
    using S = std::span<const int, 3>;

    constexpr S span1{ array.data(), 3 };
    constexpr S span2{array.begin(), array.end()};
    constexpr S span3{carray};
    constexpr S span4{array};
}

o

int main()
{
    static constexpr std::array<int, 3> array{ 0, 1, 2 };
    static constexpr int carray[3] = { 0, 1, 2 };
    using S = std::span<const int, 3>;

    constexpr S span1{ array.data(), 3 };
    constexpr S span2{array.begin(), array.end()};
    constexpr S span3{carray};
    constexpr S span4{array};
}

Ti permette di creare un constexpr std::span.


5
L'ambito non è il problema. La durata di conservazione è. Il locale statico dovrebbe funzionare.
— Eerorika,

Funziona anche se tutti sono oggetti locali di funzione all'interno di una constexprfunzione (senza esplicito static). Tali oggetti hanno una durata di archiviazione statica predefinita o è qualcosa di diverso?
— n314159

@ n314159 Non sono sicuro se ciò sia consentito o se sei caduto nel temuto: se nessuna specializzazione di una funzione constexpr è un'espressione costante fondamentale, la funzione è mal formata, nessuna clausola diagnostica richiesta. [expr.const] / 10 consente solo variabili statiche.
— NathanOliver,

@ n314159: Non sono sicuro esattamente cosa stai dicendo funziona (o "funziona"), ma fai attenzione alla differenza tra usare qualcosa come espressione costante in una funzione (constexpr o no) e usare qualcosa per costruire una costante espressione tramite una funzione constexpr.
— Davis Herring,

Potresti voler dire che i valori non statici (costanti) possono essere usati nelle espressioni costanti, ma non nei loro indirizzi .
— Davis Herring,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.