Why can't I construct a gsl::span with a brace-enclosed initializer list
When you call the vector version, the initializer list is used to create a temporary std::vector
, which is then passed to the function by const reference. This is possible, because std::vector
has a constructor, that takes an std::initializer_list<T>
as an argument.
However, gsl::span
doesn't have such a constructor and as {0,1,2,3}
doesn't have a type, it also can't be accepted by the templated constructor you mentioned (besides the fact, that std::initializer_list<T>
wouldn't satisfy the container concept anyway).
One (ugly) workaround would be of course to explicitly create a temporary array:
func(std::array<int,4>{ 0,1,2,3 });
I don't see a particular reason, why gsl::span
should not have a constructor that takes a std::initializer_list
, but keep in mind that this library is in still pretty new and under active development. So maybe it is something they overlooked, didn't have time to implement, weren't sure how to do properly or there are really some details, that would make that construct dangerous. Its probably best to ask the developers directly on github.
EDIT:
As @Nicol Bolas explains in his comment, this was by design because an initializer list like {0,1,2,3}
(and the elements within) is a temporary object and as gsl::span
is not a container in its own right (it doesn't take ownership of the elements), they think it would be too easy to accidentally create a gsl::span
that contains a dangling reference to those temporary elements.
So, while this would be OK:
func({ 0,1,2,3 });
because the lifetime of the initializer list ends after the completion of the function, something like this would create a dangling reference:
gsl::span<const int> data{ 0,1,2,3 };
func(data);
Span is non owning. Does not own storage. It is a replacement for pointer arithmetic, not a storage class.
You need to put your data in a storage class, and then if you want to do clever things with pointer arithmetic, you instead do clever things with spans.
You cannot initialize a span with an initializer list, because there is nowhere to put the data.