Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can span be constexpr?

All the constructors of std::span are declared constexpr, however I can't seem to get any of them to work in a constexpr context. Uncommenting any of the constexpr below will result in a compilation error.

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

Is it in fact possible to create a constexpr span type, since it seems like constructors can never be evaluated at compile time when they have to initialize a pointer or reference?

like image 711
Andreas Loanjoe Avatar asked Nov 20 '19 19:11

Andreas Loanjoe


Video Answer


1 Answers

You can't use non-static function local variables in a constant expression like that. You need address stability and that is only achieved by static objects. Modifying the code to

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

or

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

Allows you to create a constexpr std::span.

like image 121
NathanOliver Avatar answered Sep 29 '22 21:09

NathanOliver