Можно ли копировать std :: vector тривиально и почему?

Я столкнулся с проблемой с std::vector<T>, где T - это встроенный тип, говорящий о том, что вектор не может быть легко скопирован.

Мне было интересно, правильно ли это, и ищу причину.


person Oblivion    schedule 18.01.2019    source источник
comment
Вы всегда можете проверить с помощью std::is_trivially_copyable   -  person Passer By    schedule 18.01.2019


Ответы (2)


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

Теперь, если объект легко конструируется, нужно иметь возможность копировать / клонировать объект, просто используя memcpy(dest, &a, sizeof(a)). Если бы кто-то сделал это для vector, у него было бы 2 векторных объекта, указывающих на один и тот же буфер хранения. Это приведет к ужасному неопределенному поведению. Поэтому для копирования вектора необходимо продублировать внутреннее хранилище, продублировать его параметры, а затем установить внутренний указатель, указывающий на правильный буфер хранилища. Для этого требуется внутреннее знание объекта.

std::array, однако, имеет статический размер, установленный во время компиляции. У него нет внутренних указателей, поэтому его можно просто скопировать с помощью memcpy. Поэтому копировать - тривиально.

person doron    schedule 18.01.2019

Формально std::vector<T> (для любого T) не может быть легко копируемым, поскольку его конструктор копирования не тривиально, хотя бы потому, что он предоставляется пользователем (в отличие от неявно определенный).

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

person Igor Tandetnik    schedule 18.01.2019
comment
Его конструктор перемещения, присваивание копирования и перемещения и деструктор также являются нетривиальными. - person Barry; 18.01.2019