On Tue, Jul 2, 2019 at 1:59 AM Bjorn Reese <breese@stofanet.dk> wrote:
On 7/1/19 11:47 PM, Jorg Brown wrote:
> A vector can be empty; a string can be empty; a string_view can be
> empty; even a std::array can be empty.  So why block a std::span from
> being empty, just because its extent isn't dynamic?  I think this would
> end up blocking some compile-time programming cases.

A span with dynamic extent can be empty.

> Speaking of which, it's annoying that this doesn't currently work, due
> to data()'s implemenetation within std::array:
>
> constexpr const std::array<int, 0> ar0{};
> constexpr auto spanned_empty_array = std::span<const int, 0>{ar0};
>
> See https://godbolt.org/z/L4-9r8

It does not seem to work for begin/end (or cbegin/cend) either when
N = 0.

Sorry, I sent the wrong link; the inclusion of "constexpr" in that program triggers a bug that needs to be fixed in libc++'s implementation of std::array.  (Specifically, the bug is that std::array::data() isn't always constexpr)  If you delete the constexpr on the second line, it will compile just fine.

Here's a better longer example => https://godbolt.org/z/rki77g  which is this code, and compiles with -std=c++2a -stdlib=libc++ :

// Ref is useful for seeing (by its function signature) what the type of something is.
template<typename T> void Ref(T&&);

constexpr const std::array<int, 0> ar0{};
auto spanned_empty_array = std::span /* <int, std::dynamic_extent> */ {ar0};
constexpr int size_of_empty_span = spanned_empty_array.size();

int get_size_of_empty_span() {
  Ref(spanned_empty_array);
  return size_of_empty_span;
}

Note that the parameters to std::span are deduced here - which is the point I'm making: something that was supposed to have a static zero extent would now be deduced as having a dynamic extent.  If you comment out the template parameters to span in this code, which forces the std::span to be dynamic, then the code no longer compiles, because the size of the span is no longer known at compile time.

-- Jorg