Let's say I have a function accepting an std::span<int>
, and I want to call it with an rvalue of an std::vector<int>
:
void foo(std::span<int> s);
std::vector<int> make_vector();
int main() {
foo(make_vector());
}
This will give me an error:
Candidate function not viable: no known conversion from
std::vector<int>
tostd::span<int>
for 1st argument
Indeed, generally we don't want to convert a soon-to-be-expired vector to a span, which will become dangling the moment the vector is gone. But here we clearly do not do anything illegal.
Sure, I can store the vector in a temporary variable, and this will work:
auto v = make_vector();
foo(v);
But this is more verbose and is no longer a one-liner, which is inconvenient in some contexts.
Is there a way to tell the compiler that that's ok to do the conversion in this particular case?
If you were not planning on modifying the contents of the span
from within the function (which is usually true), you can convey your intention by explicitly qualifying the span::element_type
as const:
void foo(std::span<const int> s);
In this case, it is okay to construct a span<const int>
from an rvalue vector<int>
, even though it is not a borrowed_range. See overload (7) of the constructor of std::span
:
- Constructs a span that is a view over the range
range
; ...
- This overload participates in overload resolution only if
- ...
- either
R
satisfies borrowed_range orstd::is_const_v<element_type>
istrue