Span có thể là constexpr?


11

Tất cả các hàm tạo của std :: span đều được khai báo constexpr, tuy nhiên tôi dường như không thể khiến bất kỳ cái nào trong số chúng hoạt động trong ngữ cảnh constexpr. Việc bỏ sót bất kỳ constexpr nào dưới đây sẽ dẫn đến lỗi biên dịch.

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

Trên thực tế có thể tạo ra một kiểu nhịp constexpr không, vì có vẻ như các hàm tạo không bao giờ được đánh giá tại thời điểm biên dịch khi chúng phải khởi tạo một con trỏ hoặc tham chiếu?


Uncomment các constexprs không loại bỏ chúng.
Andreas Loanjoe

Bạn đang khởi tạo một khoảng thời gian chạy tôi có nghĩa là khởi tạo một khoảng constexpr
Andreas Loanjoe

Doh. Không chắc chắn tại sao tôi làm điều đó. không bao giờ
NathanOliver

Thật kỳ lạ, đừng hiểu tại sao điều đó lại cần thiết, nhịp chỉ sống trong phạm vi địa phương ...
Andreas Loanjoe

Liên quan chặt chẽ: stackoverflow.com/q/57545503/2069064
Barry

Câu trả lời:


13

Bạn không thể sử dụng các biến cục bộ của hàm không tĩnh trong một biểu thức không đổi như thế. Bạn cần sự ổn định địa chỉ và điều đó chỉ đạt được bởi các đối tượng tĩnh. Sửa đổi mã thành

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

hoặc là

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

Cho phép bạn tạo một constexpr std::span.


5
Phạm vi không phải là vấn đề. Thời gian lưu trữ là. Tĩnh cục bộ nên làm việc.
eerorika

Nó cũng hoạt động nếu tất cả đều là các đối tượng cục bộ của hàm trong một constexprhàm (không rõ ràng static). Các đối tượng như vậy có thời lượng lưu trữ tĩnh mặc định hay đây là một cái gì đó khác nhau?
n314159

@ n314159 Tôi không chắc là điều đó được cho phép hay nếu bạn rơi vào tình trạng sợ hãi: nếu không có sự chuyên môn hóa của hàm constexpr là một biểu thức hằng số cốt lõi thì chức năng này không được định nghĩa, không có mệnh đề cần chẩn đoán. [expr.const] / 10 chỉ cho phép các biến tĩnh.
NathanOliver

@ n314159: Tôi không chắc chắn chính xác những gì bạn đang nói (hoặc hoạt động trên mạng), nhưng hãy cẩn thận về sự khác biệt giữa việc sử dụng một biểu thức không đổi trong một hàm (constexpr hoặc no) và sử dụng một cái gì đó để tạo hằng số biểu thức thông qua hàm constexpr.
Davis Herring

Bạn có thể muốn nói rằng các giá trị không tĩnh (hằng) có thể được sử dụng trong các biểu thức không đổi, nhưng không phải là địa chỉ của chúng .
Davis Herring
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.