Kann Span constexpr sein?

11

Alle Konstruktoren von std :: span sind als constexpr deklariert, aber ich kann anscheinend keinen von ihnen dazu bringen, in einem constexpr-Kontext zu arbeiten. Das Kommentieren eines der folgenden Constexpr führt zu einem Kompilierungsfehler.

#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};
}

Ist es tatsächlich möglich, einen constexpr span-Typ zu erstellen, da Konstruktoren anscheinend niemals zur Kompilierungszeit ausgewertet werden können, wenn sie einen Zeiger oder eine Referenz initialisieren müssen?

Andreas Loanjoe
quelle
Kommentieren Sie die constexprs aus, entfernen Sie sie nicht.
Andreas Loanjoe
Sie initialisieren eine Laufzeitspanne Ich wollte eine Constexpr-Spanne initialisieren
Andreas Loanjoe
Doh. Ich bin mir nicht sicher, warum ich das getan habe. Nevermind
NathanOliver
seltsam, verstehe nicht, warum das notwendig wäre, die Spanne lebt sowieso nur innerhalb des lokalen Bereichs ...
Andreas Loanjoe

Antworten:

13

Sie können in einem solchen konstanten Ausdruck keine lokalen Variablen mit nicht statischer Funktion verwenden. Sie benötigen Adressstabilität und dies wird nur durch statische Objekte erreicht. Ändern des Codes 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};
}

oder

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};
}

Ermöglicht das Erstellen eines constexpr std::span.

NathanOliver
quelle
5
Umfang ist nicht das Problem. Lagerdauer ist. Statische lokale sollte funktionieren.
Eerorika
Es funktioniert auch, wenn alle funktionslokale Objekte innerhalb einer constexprFunktion sind (ohne explizite static). Haben solche Objekte eine statische Standardspeicherdauer oder ist dies etwas anderes?
n314159
@ n314159 Ich bin mir nicht sicher, ob das erlaubt ist oder ob Sie in den gefürchteten Zustand geraten sind: Wenn keine Spezialisierung einer constexpr-Funktion ein konstanter Kernausdruck ist, ist die Funktion schlecht geformt, keine diagnostisch erforderliche Klausel. [expr.const] / 10 erlaubt nur statische Variablen.
NathanOliver
@ n314159: Ich bin mir nicht sicher, was genau Sie sagen, funktioniert (oder "funktioniert"), aber achten Sie auf den Unterschied zwischen der Verwendung von etwas als konstantem Ausdruck in einer Funktion (constexpr oder no) und der Verwendung von etwas zum Konstruieren einer Konstante Ausdruck über eine constexpr-Funktion.
Davis Herring
Vielleicht möchten Sie sagen, dass nicht statische (konstante) Werte in konstanten Ausdrücken verwendet werden können, nicht jedoch deren Adressen .
Davis Herring