Considere o seguinte código:
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);
Este código compila e funciona bem, pois std::span
pode ser construído a partir de um std::vector
.
Agora, estou tentando envolvê-lo em uma função separada:
void do_wrap (const std::vector<float>& foo) {
std::span<float> bar (foo);
do_smth (&bar);
}
E surge o problema:
erro: nenhuma função correspondente para chamada para 'std::span<float>::span(const std::vector<float>&)'`
Mais precisamente, const std::vector<float>&
não satisfaz restrições.
Há alguma razão para isso? Estou suspeitando do const
qualificador por enquanto.
Construindo como bar (foo.data(), foo.size())
relatórios um erro semelhante.
Compilando com g++ 14.2.0, MinGW64.
Você não pode modificar
const std::vector<float>&
elementos, mas pode modificarstd::span<float>
elementos, então os dois não são compatíveis.você deveria usar um
std::span<const float>
em vez disso.observação:
std::span
é um tipo leve de passagem por valor (é um ponteiro e um tamanho), você pode passá-lo para funções por valor.Se você estiver interagindo com uma API C, então é melhor atualizar a API C para esperar que a
const float*
torne explícita sua promessa de não modificar os dados, mas se você não puder modificá-la, então você pode usarconst_cast
insidedo_smth
no limite da API C para descartar a const por sua conta e risco. Se a função realmente modificou os dados, então você terá um comportamento indefinido.Você pode escrever
do_wrap
withspan
como parâmetro e passar avector
como argumento. Se precisar fazer a conversão repetidamente, você pode querer usar esta versão dedo_wrap
, que também ilustra a técnica.Nota: A outra resposta foi publicada enquanto eu escrevia a minha. Se as funções C exigirem
const
, você pode retornar umconst span
. Modifiquei meu código para demonstrar isso.