Может ли span быть constexpr?

11

Все конструкторы std :: span объявлены constexpr, однако я не могу заставить их работать в контексте constexpr. Раскомментирование любого из constexpr ниже приведет к ошибке компиляции.

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

Действительно ли возможно создать тип span constexpr, так как кажется, что конструкторы никогда не могут быть оценены во время компиляции, когда они должны инициализировать указатель или ссылку?

Андреас Ланджо
источник
Раскомментируйте constexprs, не удаляйте их.
Андреас Loanjoe
Вы инициализируете промежуток времени выполнения, который я имел в виду для инициализации промежутка constexpr
Andreas Loanjoe
Doh. Не уверен, почему я это сделал. фигу
NathanOliver
странно, не понимаю, почему это было бы необходимо, ведь промежуток живет только внутри локальной области видимости ...
Andreas Loanjoe
Близко связаны: stackoverflow.com/q/57545503/2069064
Барри

Ответы:

13

Вы не можете использовать локальные переменные нестатических функций в таком постоянном выражении. Вам нужна стабильность адреса, и это достигается только статическими объектами. Изменение кода на

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

или

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

Позволяет создать constexpr std::span.

NathanOliver
источник
5
Сфера не проблема. Срок хранения составляет. Статический локальный должен работать.
eerorika
Это также работает, если все являются локальными объектами constexprфункции внутри функции (без явного static). У таких объектов есть статическая длительность хранения по умолчанию или это что-то другое?
n314159
@ n314159 Я не уверен, разрешено ли это, или если вы впали в ужас: если специализация функции constexpr не является основным константным выражением, функция не сформирована, пункт диагностики не требуется. [expr.const] / 10 допускает только статические переменные.
Натан Оливер
@ n314159: Я не совсем уверен, что именно то, что вы говорите, работает (или «работает»), но следует учитывать разницу между использованием чего-либо в качестве константы в функции (constexpr или нет) и использованием чего-либо для создания константы выражение через функцию constexpr.
Дэвис Херринг
Вы можете сказать, что нестатические (постоянные) значения могут использоваться в константных выражениях, но не в их адресах .
Дэвис Херринг