Reputation: 2074
A gsl::span is view of a piece of memory.
foo
is a template function that can accept either a mutable span and an immutable span.
I want the code within foo
to always only have immutable access to the piece memory.
#include <gsl/gsl> // gsl-lite
template <typename T>
void foo(gsl::span<const T> x) {}
int main() {
int arr[] = {0, 1, 2, 3, 4};
auto s1 = gsl::span<int>(arr);
foo(s1);
}
This doesn't work because no type conversion during template instantiation.
If I write the following instead:
template <typename T>
void foo(gsl::span<T> x) {}
Within foo
, x
can be a mutable span.
What is the correct fix for this use case?
Upvotes: 0
Views: 792
Reputation: 5652
How about just making a const version of the variable out of the parameter?
template <typename T>
void foo(gsl::span<T> x_raw)
{
gsl::span<const T> x { x_raw }; // add const if not already present
// use x in the code
}
Upvotes: 1
Reputation: 217593
gsl::span<const T>
has constructor accepting gsl::span<T>
. So you "just" have an issue of template deduction.
You have several ways to workaround your issue:
Be explicit at call site:
foo<int>(arr)
foo(gsl::span<const int>(arr))
Write overloads:
template <typename T>
void foo(gsl::span<const T> arr) { /* Your implementation */ }
template <typename T>
void foo(gsl::span<T> arr) { foo(gsl::span<const T>(arr)); }
Write helper functions to be less explicit at call site, for example:
template <typename T>
span<const T> as_immutable_view(span<T> s) { return s; }
and then call foo(as_immutable_view(arr))
Upvotes: 2