Consider the following code:
std::vector<float> foo = some_generator_function();
std::span<float> bar {foo};
/* Wrapper for C API that uses bar->data() and bar->size_bytes()
* if bar != nullptr, guaranteed not to change any data in bar.
* In some cases bar is constructed from a const C array.
*/
do_smth (&bar);
This code compiles and works fine, as std::span
can be constructed from a std::vector
.
Now, I'm trying to wrap it into a separate function:
void do_wrap (const std::vector<float>& foo) {
std::span<float> bar (foo);
do_smth (&bar);
}
And the problem arises:
error: no matching function for call to 'std::span<float>::span(const std::vector<float>&)'`
More precisely, const std::vector<float>&
does not satisfy constraints.
Is there any reason for this? I'm suspecting the const
qualifier for now.
Constructing as bar (foo.data(), foo.size())
reports a similar error.
Compiling with g++ 14.2.0, MinGW64.
You cannot modify const std::vector<float>&
elements, but you can modify std::span<float>
elements, so the two are not compatible.
you should be using a std::span<const float>
instead.
side note: std::span
is a lightweight pass-by-value type (it is a pointer and a size), you can pass it to functions by-value.
void do_smth(std::span<const float> arg);
void do_wrap (const std::vector<float>& foo)
{
do_smth(foo); // implicitly constructs std::span<const float>
}
If you are interacting with a C API then it is better to update the C API to expect a const float*
to make its promise of not modifying the data explicit, but if you can't modify it then you can use const_cast
inside do_smth
at the C API boundary to cast away the const at your own risk. if the function actually modified the data then you have undefined behavior.