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.