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.