Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't I construct a gsl::span with a brace-enclosed initializer list

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?

like image 875
user3467895 Avatar asked Nov 23 '15 15:11

user3467895


1 Answers

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});
}
like image 199
Bence Avatar answered Sep 22 '22 01:09

Bence