@einpoklum faz um bom trabalho ao apresentar o que span
é em sua resposta aqui . No entanto, mesmo depois de ler sua resposta, é fácil para alguém novo se estender ainda ter uma sequência de perguntas que não são totalmente respondidas, como as seguintes:
- Qual é a
span
diferença de uma matriz C? Por que não usar apenas um desses? Parece que é apenas um daqueles com o tamanho conhecido também ...
- Espere, isso soa como um
std::array
, como é span
diferente disso?
- Oh, isso me lembra, não é
std::vector
como um std::array
também?
- Estou tão confuso. :( O que é um
span
?
Então, aqui está uma clareza adicional sobre isso:
CITAÇÃO DIRETA DE SUA RESPOSTA - COM MINHAS ADIÇÕES EM NEGRITO :
O que é isso?
A span<T>
é:
- Uma abstração muito leve de uma sequência contígua de valores do tipo
T
em algum lugar da memória.
- Basicamente, uma estrutura única
{ T * ptr; std::size_t length; }
com vários métodos de conveniência. (Observe que isso é distintamente diferente de std::array<>
porque um span
possibilita métodos acessadores de conveniência, comparáveis a std::array
, por meio de um ponteiro, ao tipoT
e comprimento (número de elementos) do tipo T
, enquanto std::array
é um contêiner real que contém um ou mais valores do tipo T
.
- Um tipo não proprietário (ou seja, um "tipo de referência" em vez de um "tipo de valor"): nunca aloca nem desaloca nada e não mantém ativos os indicadores inteligentes.
Era conhecido anteriormente como array_view
e até mais cedo como array_ref
.
Essas partes ousadas são críticas para o entendimento, portanto, não as perca ou as interprete mal! A span
NÃO é uma matriz C de estruturas, nem é uma estrutura de uma matriz C do tipo T
mais o comprimento da matriz (isso seria essencialmente o que o std::array
contêiner é), NOR é uma matriz C de estruturas de ponteiros para digitar T
mais o comprimento, mas é uma estrutura única que contém um ponteiro para digitarT
e o comprimento , que é o número de elementos (do tipo T
) no bloco de memória contíguo para o qual o ponteiro para o tipo T
aponta! Dessa forma, a única sobrecarga que você adicionou usando umspan
são as variáveis para armazenar o ponteiro e o comprimento, e quaisquer funções de acessador de conveniência que você utilize que sejam span
fornecidas.
Isso é UNLIKE a std::array<>
porque, na std::array<>
verdade, aloca memória para todo o bloco contíguo, e é UNLIKE std::vector<>
porque a std::vector
é basicamente apenas um std::array
que também produz crescimento dinâmico (geralmente dobrando de tamanho) cada vez que é preenchido e você tenta adicionar algo a ele . A std::array
é de tamanho fixo e a span
nem gerencia a memória do bloco para o qual aponta, apenas aponta para o bloco de memória, sabe quanto tempo o bloco de memória tem, sabe qual é o tipo de dados em um array C na memória e fornece funções convenientes de acessador para trabalhar com os elementos nessa memória contígua .
Ele é parte do padrão C ++:
std::span
faz parte do padrão C ++ a partir do C ++ 20. Você pode ler a documentação aqui: https://en.cppreference.com/w/cpp/container/span . Para ver como usar o Google absl::Span<T>(array, length)
no C ++ 11 ou mais recente hoje , veja abaixo.
Descrições de resumo e referências principais:
std::span<T, Extent>
( Extent
= "o número de elementos na sequência, ou std::dynamic_extent
se dinâmico". Um período apenas aponta para a memória e facilita o acesso, mas NÃO o gerencia!):
- https://en.cppreference.com/w/cpp/container/span
std::array<T, N>
(observe que ele tem um tamanho fixoN
!):
- https://en.cppreference.com/w/cpp/container/array
- http://www.cplusplus.com/reference/array/array/
std::vector<T>
(cresce automaticamente de tamanho dinamicamente, conforme necessário):
- https://en.cppreference.com/w/cpp/container/vector
- http://www.cplusplus.com/reference/vector/vector/
Como posso usar span
no C ++ 11 ou posterior hoje ?
O Google abriu suas bibliotecas C ++ 11 internas na forma de sua biblioteca "Abseil". Esta biblioteca destina-se a fornecer recursos C ++ 14 a C ++ 20 e além, que funcionam no C ++ 11 e posterior, para que você possa usar os recursos de amanhã hoje. Eles dizem:
Compatibilidade com o padrão C ++
O Google desenvolveu muitas abstrações que correspondem ou se aproximam de recursos incorporados ao C ++ 14, C ++ 17 e além. O uso das versões Abseil dessas abstrações permite acessar esses recursos agora, mesmo que seu código ainda não esteja pronto para a vida em um mundo pós-C ++ 11.
Aqui estão alguns recursos e links importantes:
- Site principal: https://abseil.io/
- https://abseil.io/docs/cpp/
- Repositório do GitHub: https://github.com/abseil/abseil-cpp
span.h
cabeçalho e absl::Span<T>(array, length)
classe de modelo: https://github.com/abseil/abseil-cpp/blob/master/absl/types/span.h#L189
std::span
foi proposto em 2017. Aplica-se ao C ++ 17 ou C ++ 20. Consulte também P0122R5, visualizações span: safe-safe para seqüências de objetos . Deseja realmente segmentar esse idioma? Levará anos até que os compiladores os recuperem.