Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot construct `std::span<T>` from `const std::vector<T>&`

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.

like image 240
trexxet Avatar asked Nov 01 '25 11:11

trexxet


1 Answers

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.

like image 102
Ahmed AEK Avatar answered Nov 03 '25 04:11

Ahmed AEK