Создание std :: vector неподвижного типа - PullRequest
0 голосов
/ 02 марта 2019

У меня есть std::vector с именем args (я не знаю размер вектора во время компиляции) и неподвижный тип NonMoveable.

Я хочу создать вектор изтот же размер, что и у аргументов, так что он равен {NonMovable(args[0], additional_arg), NonMovable(args[1], additional_arg), …, NonMovable(args.back(), additional_arg)}

. Мне не нужно менять размер вектора позже.Как мне это сделать?

Я не могу reserve(), тогда emplace_back(), потому что emplace_back() требует перемещения (чтобы разрешить перераспределение, которое в моем случае невозможно)

Я не делаюхочу использовать std::list, потому что он не является смежным.

Ответы [ 2 ]

0 голосов
/ 02 марта 2019

Если вы хотите, чтобы элементы были смежными, вы можете использовать старую добрую 2-кратную динамическую конструкцию массива:

// allocate a dynamic array
NonMoveable *mv = std::allocator<NonMoveable>().allocate(args.size());

// use inplace new to construct the NonMoveable elements
for (unsigned int i = 0; i < args.size(); i++) {
    new(mv + i) NonMoveable(args[i], additional_arg);
}

...  // use the dynamic array

// Explicitely delete the elements
for (unsigned int i = 0; i < args.size(); i++) {
    mv[i].~NonMoveable();
}

// and de-allocate
std::allocator<NonMoveable>().deallocate(mv, args.size());

Это скорее C-ish, но удовлетворяет смежным требованиям.Конечно, это должно быть заключено в специальный контейнер для автоматического уничтожения и удаления при уничтожении контейнера.

0 голосов
/ 02 марта 2019

Вы можете:

  • Иметь vector<unique_ptr<T>> или vector<optional<T>> или vector<some_other_defer_storage_mechanism<T>> вместо просто vector<T> - это все типы оболочек, которые добавляют некоторые функции T, не затрагивая T (unique_ptr<T> делает его подвижным, optional<T> обеспечивает построение по умолчанию, поэтому вы можете построить с правильным размером, тогда emplace() в пределах optional и т. Д.)
  • Использовать deque<T>, что нетребуется подвижность для emplace_back (хотя вы теряете смежность)
  • Напишите свой собственный динамический массив, примерно эквивалентный pair<unique_ptr<T[]>, size_t>, который просто выделяет пространство для n T с, а затем разместите новости накаждый из них, гарантируя, что разрушение делает правильные вещи.Это не так уж плохо для реализации - так как вы не будете изменять размер, вам нужно поддерживать очень минимальное количество общих операций.

Какой из этих ответов является лучшим, действительно зависит,

...