std :: dynarray vs std :: vector

84

C ++ 14 przedstawia std::dynarray:

std :: dynarray to kontener sekwencji, który hermetyzuje tablice o rozmiarze, który jest ustalony w konstrukcji i nie zmienia się przez cały okres istnienia obiektu.

std::dynarraymuszą być przydzielane w czasie wykonywania tak samo jak std::vector.

Więc jakie są korzyści i wykorzystanie, std::dynarraypodczas gdy możemy używać tego, std::vectorktóry jest bardziej dynamiczny (a także skalowalny)?

masoud
źródło
1
Hej, od kiedy „C ++ 14” jest tagiem? Szukałem tego innego dnia i nie było ...
Kerrek SB
1
Czy std::valarrayzmieniono nazwę na std::dynarray? Jaka jest dynamika, std::dynarraykiedy nie można zmienić jej rozmiaru?
yasouser
9
@yasouser, nie, to nie ma z tym nic wspólnego valarray. Jest dynamiczna, ponieważ długość tablicy jest wartością w czasie wykonywania, nie musi być znana w czasie kompilacji, w przeciwieństwie dostd::array
Jonathan Wakely
21
Zauważ, że na posiedzeniu Komitetu ds. Standardów C ++ w zeszłym tygodniu dynarrayzostał usunięty z C ++ 14 i umieszczony w przyszłej Specyfikacji Technicznej (pomyśl o tym jako o nowej wersji TR1), ponieważ ma poważne problemy techniczne.
Pete Becker
2
dynarray nie jest już częścią wersji roboczej C ++ 14
cassinaj

Odpowiedzi:

90

Więc jakie są korzyści i zastosowanie std::dynarray, kiedy możemy użyć tego, std::vectorktóry jest bardziej dynamiczny (o zmiennym rozmiarze)?

dynarrayjest mniejszy i prostszy niż vector, ponieważ nie musi zarządzać osobnymi wartościami rozmiaru i pojemności oraz nie musi przechowywać alokatora.

Jednak główna korzyść związana z wydajnością ma pochodzić z faktu, że implementacje są zachęcane do alokacji dynarrayna stosie, jeśli to możliwe, unikając alokacji sterty. na przykład

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

Ta optymalizacja wymaga współpracy kompilatora, nie można jej zaimplementować jako czystego typu bibliotecznego, a niezbędna magia kompilatora nie została zaimplementowana i nikt nie jest pewien, jak łatwo to zrobić. Ze względu na brak doświadczenia we wdrożeniach, na posiedzeniu komitetu C ++ w Chicago w zeszłym tygodniu zdecydowano się wyciągnąć std::dynarrayz C ++ 14 i wydać oddzielny dokument definiujący rozszerzenia tablic TS (specyfikacja techniczna) std::experimental::dynarrayi tablice związane ze środowiskiem uruchomieniowym (ARB, podobne do C99 VLA). Oznacza to, std::dynarrayże prawie na pewno nie będzie w C ++ 14.

Jonathan Wakely
źródło
1
Świetnie, zastanawiałem się, czy na wolności są jakieś nietrywialne implementacje dynarray. Zawsze uważałem, że potrzebujesz dwóch niezależnych wdrożeń istniejącej praktyki, zanim coś zostanie zakwalifikowane do normalizacji.
Kerrek SB
Nie, nie ma żadnych znanych implementacji alokacji stosu dynarray. Chociaż doświadczenie w implementacji jest bardzo przydatne, nie ma ustalonej reguły, która tego wymaga (ale niektórzy twierdzą, że powinno być!)
Jonathan Wakely,
tu tylko burza mózgów, ale co z utworzeniem 2 funkcji: std :: dynarray make_dyn_autostorage (int) i std :: dynarray make_dyn_heap (int)?
Podawaj Laurijssen
2
@KerrekSB, tak, ruch biblioteki nr 10 w Chicago brzmiał: „Przenieś, tworzymy dokument roboczy dla planowanego TS Array Extensions, usuń edycje zastosowane na płycie CD C ++ 14 przez dwa dokumenty N3639 ,„ Tablice o rozmiarze runtime z automatycznym czas przechowywania (wersja 5) " N3662 ," C ++ Dynamic Arrays (dynarray) "i polecić edytorowi projektu Array Extensions TS, aby zastosować te słowa do dokumentu roboczego Array Extensions jako jego początkowej zawartości."
Jonathan Wakely
3
@ h9uest to nie ma nic wspólnego z „gośćmi z C ++”, są to oficjalne nazwy produktów komitetu technicznego ISO , patrz iso.org/iso/home/standards_development/… i iso.org/iso/home/standards_development /…
Jonathan Wakely
31

Jak sam powiedziałeś, std::dynarraydotyczy tablicy dynamicznej o stałym rozmiarze . Nie można zmieniać rozmiaru. To z grubsza rzecz biorąc poprawę w ciągu new T[N]i nad std::unique_ptr<T[]>(new T[N]).

Brak konieczności zmiany rozmiaru lub zarządzania pojemnością oznacza, że ​​możesz wdrożyć strukturę danych z mniejszą złożonością i mniejszą przestrzenią.

Co więcej, std::dynarrayjest dziwnym zwierzęciem, które pozwala implementacji zaimplementować go na różne, niespecyficzne sposoby, np. Można umieścić tablicę na stosie. Wywołanie funkcji alokacji jest „opcjonalne”. Możesz określić alokator do konstruowania elementów tablicy, ale nie jest to część typu.

Można również zastanawiać się, dlaczego musimy std::dynarray i tablice o zmiennej długości. Umowy VLA w C ++ 14 są znacznie bardziej restrykcyjne; mogą być tylko lokalnymi, automatycznymi zmiennymi i nie oferują możliwości określenia zasad alokacji i oczywiście nie mają standardowego interfejsu kontenera.


Kilka przykładów z 23.3.4.2 „bieżącej wersji roboczej” (weź to, pamięć podręczna Google):

explicit dynarray(size_type c);

Efekty: Przydziela miejsce na celementy. Może wywoływać plik global operator new.

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

Efekty: równoważne z poprzednimi konstruktorami, z tą różnicą, że każdy element jest konstruowany z konstrukcją use-alokator .

To, czy możesz użyć danego alokatora do skonstruowania elementów tablicy, jest cechą globalną:

szablon struct uses_allocator, Alloc>: true_type {};

Wymaga: Alloc musi być alokatorem (17.6.3.5). [ Uwaga: Specjalizacja tej cechy informuje inne komponenty biblioteki, które dynarraymożna skonstruować za pomocą alokatora, nawet jeśli nie ma ona zagnieżdżonego alokatora_type.]

Edycja: odpowiedź Jonathana Wakely'ego z pewnością będzie znacznie bardziej autorytatywna i wnikliwa.

Kerrek SB
źródło
Przekazywanie alokatora do dynarraykonstruktora nigdy nie jest używane do alokacji, jest używane tylko jako argument do konstruktorów elementów (przy użyciu „konstrukcji używa alokatora”). Dlatego nie możesz zapytać, czy alokator został użyty: ponieważ nigdy nie jest.
Jonathan Wakely
@JonathanWakely: Ach, źle to zrozumiałem. Dzięki, naprawione!
Kerrek SB