std :: dynarray против std :: vector

84

C ++ 14 представляет std::dynarray:

std :: dynarray - это контейнер последовательности, который инкапсулирует массивы с размером, который фиксируется при построении и не изменяется на протяжении всего времени существования объекта.

std::dynarrayдолжен быть выделен во время выполнения так же, как std::vector.

Итак, каковы преимущества и возможности использования, в std::dynarrayто время как мы можем использовать std::vectorболее динамичный (а также масштабируемый)?

Масуд
источник
1
Эй, с каких это пор "C ++ 14" стал тегом? Я искал это на днях, и его не существовало ...
Керрек С.Б.
1
Является ли std::valarrayпереименован std::dynarray? Что динамично, std::dynarrayкогда его нельзя изменить размер?
yasouser
9
@yasouser, нет, тут не причем valarray. Он динамический, потому что длина массива является значением времени выполнения, его не нужно знать во время компиляции, в отличие отstd::array
Джонатан Уэйкли,
21
Обратите внимание, что на заседании комитета по стандартам C ++ на прошлой неделе он dynarrayбыл удален из C ++ 14 и помещен в будущую техническую спецификацию (подумайте об этом как о новой версии TR1), потому что он имеет некоторые серьезные технические проблемы.
Пит Беккер
2
dynarray больше не является частью проекта C ++ 14
cassinaj

Ответы:

90

Итак, каковы преимущества и возможности использования std::dynarray, когда мы можем использовать std::vectorболее динамичный (масштабируемый)?

dynarray меньше и проще, чем vector , потому что ему не нужно управлять отдельными значениями размера и емкости, и ему не нужно хранить распределитель.

Однако основной выигрыш в производительности должен исходить от того факта, что реализациям рекомендуется размещать dynarrayпамять в стеке, когда это возможно, избегая любого выделения кучи. например

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

Эта оптимизация требует сотрудничества со стороны компилятора, она не может быть реализована в виде чистой библиотеки, а необходимая магия компилятора не реализована, и никто не уверен, насколько легко это сделать. Из-за отсутствия опыта реализации на заседании комитета C ++ в Чикаго на прошлой неделе было решено отказаться std::dynarrayот C ++ 14 и выпустить отдельный документ TS (техническая спецификация) расширений std::experimental::dynarrayмассивов, определяющий и массивы ограничений времени выполнения (ARB, аналогичные в C99 VLA.) Это означает, std::dynarrayчто почти наверняка не будет в C ++ 14.

Джонатан Уэйкли
источник
1
Отлично, мне было интересно, есть ли какие- нибудь нетривиальные реализации dynarrayв дикой природе. Я всегда думал, что вам нужны две независимые реализации существующей практики, прежде чем что-то станет подходящим для стандартизации.
Керрек СБ
Нет, нет известных реализаций распределения стека dynarray. Хотя опыт внедрения очень полезен, нет установленного правила, требующего его (но некоторые говорят, что оно должно быть!)
Джонатан Уэйкли,
просто мозговой штурм, но как насчет создания двух функций: std :: dynarray make_dyn_autostorage (int) и std :: dynarray make_dyn_heap (int)?
Обслужить Лаурийссен
2
@KerrekSB, да, движение библиотеки 10 в Чикаго было: «Переместите, мы создадим рабочий документ для запланированного TS расширений массивов, удалим правки, примененные к компакт-диску C ++ 14 двумя документами N3639» , «Массивы рабочего размера с автоматическим продолжительность хранения (версия 5) « N3662 ,« C ++ Dynamic Arrays (dynarray) »и указать редактору проекта Array Extensions TS применить эти слова к рабочему документу Array Extensions в качестве исходного содержимого».
Джонатан Уэйкли,
3
@ h9uest, который не имеет ничего общего с "ребятами из C ++", это официальные названия результатов технического комитета ISO , см. iso.org/iso/home/standards_development/… и iso.org/iso/home/standards_development /…
Джонатан Уэйкли
31

Как вы сами сказали, std::dynarrayэто для динамического массива фиксированного размера . Его размер нельзя изменить. Грубо говоря, это улучшение снова new T[N]и снова std::unique_ptr<T[]>(new T[N]).

Отсутствие необходимости изменять размер или управлять емкостью означает, что вы можете реализовать структуру данных с меньшей сложностью и на меньшем пространстве.

Более того, std::dynarray это странное животное, которое позволяет реализации реализовать его разными, неспецифическими способами, например, можно поместить массив в стек. Вызов функции распределения «необязателен». Вы можете указать распределитель для создания элементов массива, но он не является частью типа.

Вы также можете задаться вопросом, зачем нам std::dynarray и массивы переменной длины. VLA в C ++ 14 гораздо более строгие; они могут быть только локальными автоматическими переменными и не предлагают возможности указать политику распределения, и, конечно же, у них нет стандартного интерфейса контейнера.


Некоторые примеры из 23.3.4.2 "текущего черновика" (возьмите это, кеш Google):

explicit dynarray(size_type c);

Эффекты: выделяет место для хранения cэлементов. Может или не может вызывать глобальный operator new.

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

Эффекты: Эквивалентен предыдущим конструкторам, за исключением того, что каждый элемент создается с помощью конструкции uses-allocator .

Независимо от того или нет , вы можете использовать данный аллокатор для построения элементов массива является глобальной чертой:

шаблон struct uses_allocator, Alloc>: true_type {};

Требуется: Alloc должен быть Распределителем (17.6.3.5). [ Примечание: специализация этого признака сообщает другим компонентам библиотеки, которые dynarrayмогут быть созданы с помощью распределителя, даже если он не имеет вложенного типа allocator_type.]

Изменить: ответ Джонатана Уэйкли должен быть гораздо более авторитетным и проницательным.

Керрек С.Б.
источник
Передача распределителя в dynarrayконструктор никогда не используется для распределения, она используется только в качестве аргумента для конструкторов элементов (с использованием «конструкции использует-распределитель»). Вот почему вы не можете запросить, использовался ли распределитель: потому что его никогда не было.
Джонатан Уэйкли,
@JonathanWakely: Ах, я неправильно это понял. Спасибо, исправлено!
Керрек SB 01