Czy rozpiętość może być constexpr?


11

Wszystkie konstruktory std :: span są zadeklarowane jako constexpr, jednak nie wydaje się, aby którykolwiek z nich działał w kontekście constexpr. Odznaczenie któregokolwiek z poniższych constexpr spowoduje błąd kompilacji.

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

Czy w rzeczywistości jest możliwe utworzenie typu rozpiętości constexpr, ponieważ wydaje się, że konstruktorów nigdy nie można ocenić w czasie kompilacji, gdy muszą zainicjować wskaźnik lub odwołanie?


Odkomentuj constexprs nie usuwaj ich.
Andreas Loanjoe,

Inicjujesz przedział czasu wykonywania Chciałem zainicjować przedział constexpr
Andreas Loanjoe,

Doh Nie jestem pewien, dlaczego to zrobiłem. Nevermind
NathanOliver

dziwne, nie rozumiem, dlaczego byłoby to konieczne, tak czy inaczej rozpiętość żyje tylko w zasięgu lokalnym ...
Andreas Loanjoe,

Odpowiedzi:


13

Nie można używać zmiennych lokalnych o funkcji niestatycznej w takim wyrażeniu stałym. Potrzebujesz stabilności adresu i jest to osiągane tylko przez obiekty statyczne. Modyfikacja kodu na

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

lub

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

Pozwala utworzyć constexpr std::span.


5
Zakres nie jest problemem. Czas przechowywania wynosi. Statyczny lokalny powinien działać.
eerorika

Działa również, jeśli wszystkie są lokalnymi obiektami constexprfunkcji w ramach funkcji (bez wyraźnego określenia static). Czy takie obiekty mają domyślny czas przechowywania statycznego, czy to coś innego?
n314159,

@ n314159 Nie jestem pewien, czy jest to dozwolone, czy też wpadłeś w przerażenie: jeśli żadna specjalizacja funkcji constexpr nie jest podstawowym stałym wyrażeniem, funkcja jest źle sformułowana, brak wymaganej diagnostycznej klauzuli. [expr.const] / 10 dopuszcza tylko zmienne statyczne.
NathanOliver,

@ n314159: Nie jestem pewien, co dokładnie mówisz, działa (lub „działa”), ale uważaj na różnicę między użyciem czegoś jako stałego wyrażenia w funkcji (constexpr lub no) a użyciem czegoś do skonstruowania stałej wyrażenie za pomocą funkcji constexpr.
Davis Herring

Możesz powiedzieć, że wartości niestatyczne (stałe) mogą być używane w wyrażeniach stałych, ale nie w ich adresach .
Davis Herring
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.