Bisakah span menjadi constexpr?

11

Semua konstruktor std :: span dideklarasikan dengan constexpr, namun sepertinya saya tidak bisa membuat mereka bekerja dalam konteks constexpr. Membatalkan komentar salah satu dari constexpr di bawah ini akan menghasilkan kesalahan kompilasi.

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

Apakah mungkin untuk membuat tipe span constexpr, karena sepertinya konstruktor tidak pernah dapat dievaluasi pada waktu kompilasi ketika mereka harus menginisialisasi pointer atau referensi?

Andreas Loanjoe
sumber
Batalkan komentar pada constexprs jangan hapus mereka.
Andreas Loanjoe
Anda menginisialisasi rentang runtime yang saya maksud untuk menginisialisasi rentang constexpr
Andreas Loanjoe
Doh. Tidak yakin mengapa saya melakukan itu. nevermind
NathanOliver
aneh, tidak mengerti mengapa itu perlu rentang hanya tinggal di dalam lingkup lokal saja ...
Andreas Loanjoe

Jawaban:

13

Anda tidak dapat menggunakan variabel lokal fungsi non-statis dalam ekspresi konstan seperti itu. Anda memerlukan stabilitas alamat dan itu hanya dicapai oleh objek statis. Memodifikasi kode menjadi

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

atau

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

Memungkinkan Anda membuat constexpr std::span.

NathanOliver
sumber
5
Lingkup bukan masalah. Durasi penyimpanan adalah. Lokal statis harus bekerja.
eerorika
Ini juga berfungsi jika semua adalah objek fungsi lokal dalam suatu constexprfungsi (tanpa eksplisit static). Apakah objek tersebut memiliki durasi penyimpanan statis default atau ini sesuatu yang berbeda?
n314159
@ n314159 Saya tidak yakin apakah itu dibolehkan atau jika Anda telah jatuh ke dalam ketakutan: jika tidak ada spesialisasi fungsi constexpr adalah ekspresi konstanta inti fungsi tidak terbentuk, tidak ada klausa diagnostik yang diperlukan. [expr.const] / 10 hanya memungkinkan variabel statis.
NathanOliver
@ n314159: Saya tidak yakin persis apa yang Anda katakan berfungsi (atau "bekerja"), tapi hati-hati dengan perbedaan antara menggunakan sesuatu sebagai ekspresi konstan dalam suatu fungsi (constexpr atau tidak) dan menggunakan sesuatu untuk membangun konstanta ekspresi melalui fungsi constexpr.
Davis Herring
Anda mungkin ingin mengatakan bahwa nilai - nilai non-statis (konstan) dapat digunakan dalam ekspresi konstan, tetapi bukan alamatnya .
Davis Herring