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
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.