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.
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