Как добавить данные char в std :: vector, не вызывая копию - PullRequest
1 голос
/ 24 июня 2019

У меня есть вектор символов, который содержит некоторые элементы данных.

std::vector<unsigned char> data_1;

У меня есть неподписанный символ *, который указывает на другой набор элементов данных.

unsigned char * data_2;

Вопрос:
Есть ли способ, которым я могу объединить data_2 в data_1, который является вектором, вообще не вызывая копию элементов данных?

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

Ответы [ 4 ]

5 голосов
/ 24 июня 2019

Есть ли способ, которым я могу объединить данные_2 в данные_1, которые являются вектором, вообще не вызывая копию элементов данных?

Нет.Все способы вставки элементов в вектор требуют копирования (или перемещения) каждого элемента хотя бы один раз.

Я читал о семантике перемещения, о которой идет речь в этом обсуждении, но я немного не уверен, возможно ли это вэта ситуация у меня здесь.

Перемещение символа аналогично копированию символа.Различие относится только к типам классов с нетривиальным конструктором перемещения или оператором назначения перемещения.

Это было бы невозможно, даже если бы data_2 был std::vector<unsigned char>?

Добавление без копирования (или перемещения) было бы невозможно даже тогда.

Sidenote 1: Вы можете заменить все содержимое одного вектора содержимым другого вектора без копирования (или перемещения) каких-либо элементов с помощью оператора присваивания перемещения вектора.

Sidenote 2: Вы можете объединить два экземпляра контейнеров на основе узлов, таких как std::list s, std::set s, std::map s и их неупорядоченные аналоги, без копирования (или перемещения) любого из элементов.

2 голосов
/ 24 июня 2019

Нет, вы не можете этого сделать.

  • Векторные данные хранятся смежно, поэтому, если ваши буферы не были каким-либо образом взаимными (а это не так), по крайней мере один из них необходимо переместить (читай: скопировать)

  • Векторы не могут владеть существующей памятью (ваша unsigned char* data_2)

  • Векторы не могут владеть двумя блоками памяти одновременно (гипотетически std::vector<unsigned char> data_2)

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

1 голос
/ 24 июня 2019

Нет.vector хранятся непрерывно;хотя вы могли бы избежать перераспределения data_1, reserve выделив достаточно места для полного размера объединенных данных перед заполнением data_1, вы не можете избежать фактической копии байтов;данные должны быть перемещены в положение, смежное с существующими данными в data_1, и vector не может этого избежать.

0 голосов
/ 26 июня 2019

Да, вы можете.Но тогда вам понадобится специальный распределитель для вектора.

По умолчанию vector использует std::allocator, и вы можете использовать vector::get_allocator для получения объекта распределителя.Вы можете попробовать использовать метод allocator::construct do для некоторых манипуляций (я не стал копать глубже).

Когда вы создаете экземпляр vector, вы можете передать пользовательский распределитель в вектор, что поможетиспользовать уже выделенную память ( размещение нового ) или любую другую функцию выделения памяти. Эта статья может помочь.

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

...