According to the C++ Core Guidelines, I should use a gsl::span to pass a half-open sequence.
I think that means that instead of writing a function like:
void func(const std::vector<int>& data) {
for (auto v : data) std::cout << v << " ";
}
I should prefer:
void func(gsl::span<const int> data) {
for (auto v : data) std::cout << v << " ";
}
Which has the advantage that it does not assume the caller has their data in a vector
, or force them to construct a temporary vector
. They could pass a std::array
for example.
But a common use-case is to pass a brace-enclosed initializer list:
func({0,1,2,3})
This works for a function taking a std::vector
but for a function taking a gsl::span
I get the error message:
error C2664: 'void func(gsl::span)' : cannot convert argument 1 from 'initializer-list' to 'gsl::span'
It looks like gsl::span
has a templated constructor designed to take any container.
Is this just something missing from the Microsoft GSL implementation or is there a good reason to prevent this practice?
This now works with absl::Span
. The following example is copied from https://abseil.io/tips/93:
void TakesSpan(absl::Span<const int> ints);
void PassALiteral() {
// Span does not need a temporary allocation and copy, so it is faster.
TakesSpan({1, 2, 3});
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With