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

Відповіді:


89

Отже, які переваги та використання 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дикої природи. Я завжди думав, що вам потрібні дві незалежні реалізації існуючої практики, перш ніж щось стане придатним для стандартизації.
Kerrek SB

Ні, немає відомих реалізацій розподілу стеків dynarray. Хоча досвід впровадження є дуже корисним, не існує встановленого правила, яке б вимагало цього (але деякі сказали б, що воно повинно бути!)
Джонатан Уейклі

просто мозковий штурм тут, а як щодо створення 2-х функцій: std :: dynarray make_dyn_autostorage (int) та std :: dynarray make_dyn_heap (int)?
Обслуговувати Laurijssen

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, Alloc>: true_type {};

Потрібно: Alloc повинен бути розподілювачем (17.6.3.5). [ Примітка: Спеціалізація цієї ознаки інформує про інші компоненти бібліотеки, які dynarrayможна сконструювати за допомогою розподільника, хоча він і не має вкладеного типу allocator_.]

Редагувати: відповідь Джонатана Уейклі обов’язково буде набагато авторитетнішою та проникливішою.


Передача розподільника dynarrayконструктору ніколи не використовується для розподілу, вона використовується лише як аргумент конструкторів елементів (використовуючи "конструкцію-розподільник використання"). Ось чому ви не можете запитати, чи був використаний розподільник: адже він ніколи не є.
Джонатан Уейклі

@JonathanWakely: Ах, я це неправильно зрозумів. Дякую, виправлено!
Kerrek SB
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.