std :: dynarray vs std :: vector

84

C ++ 14 apresenta std::dynarray:

std :: dynarray é um contêiner de sequência que encapsula matrizes com um tamanho que é fixo na construção e não muda durante a vida útil do objeto.

std::dynarraydeve ser alocado em tempo de execução da mesma forma que std::vector.

Então, quais são os benefícios e o uso de std::dynarrayenquanto podemos usar, std::vectorque é mais dinâmico (e também redimensionável)?

Masoud
fonte
1
Ei, desde quando "C ++ 14" é uma tag? Eu estava procurando por isso outro dia e não existia ...
Kerrek SB
1
Foi std::valarrayrenomeado como std::dynarray? O que é dinâmico std::dynarrayquando não pode ser redimensionado?
yasouser
9
@yasouser, não, não tem nada a ver com isso valarray. É dinâmico porque o comprimento da matriz é um valor de tempo de execução, não precisa ser conhecido em tempo de compilação, ao contrário destd::array
Jonathan Wakely
21
Observe que na reunião do Comitê de Padrões C ++ na semana passada, dynarrayfoi removido do C ++ 14 e colocado em uma Especificação Técnica futura (pense nisso como uma nova versão do TR1) porque tem alguns problemas técnicos sérios.
Pete Becker
2
dynarray não faz mais parte do projeto C ++ 14
cassinaj

Respostas:

89

Então, quais são os benefícios e o uso de std::dynarray, quando podemos usar o std::vectorque é mais dinâmico (redimensionável)?

dynarrayé menor e mais simples do que vector, porque não precisa gerenciar valores separados de tamanho e capacidade e não precisa armazenar um alocador.

No entanto, o principal benefício de desempenho deve vir do fato de que as implementações são encorajadas a alocar dynarrayna pilha quando possível, evitando qualquer alocação de heap. por exemplo

std::dynarray<int> d(5);   // can use stack memory for elements
auto p = new std::dynarray<int>(6);  // must use heap memory for elements

Essa otimização requer cooperação do compilador, não pode ser implementada como um tipo de biblioteca puro e a mágica do compilador necessária não foi implementada e ninguém tem certeza de como isso é fácil de fazer. Por causa da falta de experiência de implementação, na reunião do comitê C ++ em Chicago na semana passada, foi decidido retirar std::dynarraydo C ++ 14 e emitir um documento separado de extensões de matriz TS (especificação técnica) definindo std::experimental::dynarraye matrizes de limite de tempo de execução (ARBs, semelhantes para VLAs C99.) Isso significa std::dynarrayque quase certamente não estará em C ++ 14.

Jonathan Wakely
fonte
1
Ótimo, eu queria saber se havia alguma implementação não trivial do dynarray. Sempre pensei que você precisava de duas implementações independentes da prática existente antes que algo se tornasse elegível para padronização.
Kerrek SB
Não, não há implementações conhecidas de alocação de pilha dynarray. Embora a experiência de implementação seja muito útil, não há uma regra definida exigindo-a (mas alguns diriam que deveria!)
Jonathan Wakely
apenas brainstorming aqui, mas que tal criar 2 funções: std :: dynarray make_dyn_autostorage (int) e std :: dynarray make_dyn_heap (int)?
Sirva Laurijssen em
2
@KerrekSB, sim, o movimento da biblioteca 10 em Chicago foi: "Vamos criar um documento de trabalho para um Array Extensions TS planejado, remover as edições aplicadas ao CD C ++ 14 pelos dois papéis N3639 ," Arrays em tempo de execução com automático duração de armazenamento (revisão 5) " N3662 ," C ++ Dynamic Arrays (dynarray) "e direcionar o editor do projeto Array Extensions TS para aplicar essas palavras ao artigo de trabalho Array Extensions como conteúdo inicial.
Jonathan Wakely,
3
@ h9uest que não tem nada a ver com "os caras do C ++", esses são os nomes oficiais para os resultados de um comitê técnico ISO , consulte iso.org/iso/home/standards_development/… e iso.org/iso/home/standards_development /…
Jonathan Wakely
31

Como você mesmo disse, std::dynarrayé para um array dinâmico de tamanho fixo . Não é redimensionável. É grosso modo uma melhoria ao longo new T[N]e mais std::unique_ptr<T[]>(new T[N]).

Não precisar redimensionar ou gerenciar a capacidade significa que você pode implementar a estrutura de dados com menos complexidade e em menos espaço.

Além disso, std::dynarrayé um animal estranho que permite a implementação para implementá-lo de maneiras diferentes e não específicas, por exemplo, é possível colocar o array na pilha. Chamar uma função de alocação é "opcional". Você pode especificar um alocador para construir os elementos da matriz, mas isso não faz parte do tipo.

Você também pode perguntar por que precisamos std::dynarray e matrizes de comprimento variável. Os VLAs em C ++ 14 são muito mais restritivos; elas podem ser apenas variáveis ​​locais automáticas e não oferecem nenhuma maneira de especificar uma política de alocação e, claro, não têm uma interface de contêiner padrão.


Alguns exemplos de 23.3.4.2 de um "rascunho atual" (veja isso, cache do Google):

explicit dynarray(size_type c);

Efeitos: aloca armazenamento para celementos.Pode ou não invocar o global operator new.

template <class Alloc>
dynarray(size_type c, const Alloc& alloc);

Efeitos: Equivalente aos construtores anteriores, exceto que cada elemento é construído com a construção de alocador de usos .

Se você ou não pode usar um determinado alocador para construir os elementos da matriz, é uma característica global:

template struct usa_allocator, Alloc>: true_type {};

Requer: Alloc deve ser um Alocador (17.6.3.5). [ Nota: A especialização desta característica informa outros componentes da biblioteca quedynarray podem ser construídos com um alocador, mesmo que não tenha um alocador_type aninhado.]

Edit: A resposta de Jonathan Wakely tende a ser muito mais confiável e perspicaz.

Kerrek SB
fonte
Passar um alocador para dynarrayo construtor de nunca é usado para alocação, é usado apenas como um argumento para os construtores dos elementos (usando "construção usa-alocador"). É por isso que você não pode consultar se o alocador foi usado: porque nunca é.
Jonathan Wakely,
@JonathanWakely: Ah, não entendi bem. Obrigado, consertado!
Kerrek SB