Копирование векторной ссылки на другую - PullRequest
1 голос
/ 13 января 2011

У меня есть структура, скажем, SubscriptionData. Две переменные типа объявлены в функции 1.

SubscriptionData aSubscriptionData;
SubscriptionData aResultSubscriptionData;

Структура сама по себе имеет другую структуру, которая в свою очередь имеет вектор другой структуры. Вектор указан ниже

aSubscriptionData.apn_config_file.apn_config

Я правильно инициализировал структуры. Теперь я вызываю функцию для заполнения aSubscriptionData. Затем я вызываю другую функцию, прототип которой приведен ниже.

void breakSubDataLen(ImsMsg::SubscriptionData& aSubscriptionData, ImsMsg::SubscriptionData& aResultSubscriptionData);

В функции breakSubDataLen () предполагается копировать элементы из aSubscriptionData.begin () + 3 в aSubscriptionData.end () в структуру aResultSubscriptionData.

Я делаю для этого следующую операцию.

std::copy(aSubscriptionData.apn_config_file.apn_config.begin() + 3, 
    aSubscriptionData.apn_config_file.apn_config.end(),
    aResultSubscriptionData.apn_config_file.apn_config.begin());

Кажется, это не работает. Кто-нибудь может мне помочь?

Ответы [ 2 ]

4 голосов
/ 13 января 2011

std::copy не выделяет элементы;Вы должны убедиться, что в целевом диапазоне достаточно места для размещения всех элементов в исходном диапазоне.

Обычный способ сделать это - использовать std::back_inserter, который вызывает push_back для вставки каждого элемента в контейнер:

std::copy(source.begin(), source.end(), std::back_inserter(destination));

Другой распространенный подход заключается в предварительном выделении достаточного пространства впоследовательность назначения, использующая resize:

destination.resize(std::distance(source.begin(), source.end()));
std::copy(source.begin(), source.end(), destination.begin());

Разумеется, эти два подхода имеют различное поведение.При std::back_inserter все элементы в последовательности сохраняются, а новые элементы вставляются после существующих элементов.При подходе resize все существующие элементы перезаписываются.Вы также можете использовать подход resize и сохранить любые существующие элементы:

const std::size_t original_size = destination.size();
destination.resize(destination.size() + 
                   std::distance(source.begin(), source.end());

std::copy(source.begin(), source.end(), destination.begin() + original_size);

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

3 голосов
/ 13 января 2011

Передав aResultSubscriptionData.apn_config_file.apn_config.begin() в качестве третьего аргумента std::copy, вы сообщаете ему, что выделили достаточно места для него , присваивая элементы, начинающиеся с .begin().Если вектор содержит 0 элементов, то явно .begin() или .begin() + X не относится к действительному итератору.Это сработало бы, если вектор уже содержал достаточно элементов или если его размер был изменен, и в этом случае он скопировал бы элементы в новый вектор.

Скорее всего, вы хотите использовать vector Вставка диапазона.Я думаю, это будет намного эффективнее:

aResultSubscriptionData.apn_config_file.apn_config.insert(0, aSubscriptionData.apn_config_file.apn_config.begin() + 3, aSubscriptionData.apn_config_file.apn_config.end());
...