Как мне правильно скопировать заданный диапазон вектора в другой вектор, используя std::copy?

#c 98 #mbed

#c 98 #mbed

Вопрос:

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

Я хотел бы переместить элементы из sourceVect в destVect , при этом элементы между sourceVect[1] to sourceVect[1 numToCopy] перемещаются в начало sourceVect. Я попытался сделать это следующим образом:

 vector<int> destVect;
vector<int> sourceVect = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
int numToCopy = 7;

vector<int>::iterator itSource = sourceVect.begin();
vector<int>::iterator itSourceEnd = sourceVect.begin();
advance(itSource, 1);
advance(itSourceEnd, 1 numToCopy);

std::copy(itSource, itSourceEnd, destVect.begin());             //copy(first,last,output vector ite)


for (vector<int>::iterator it = destVect.begin(); it != destVect.end();   it)
    cout << ' ' << *it;
  

Но я получаю ошибку утверждения отладки, векторный итератор смещение вне диапазона в Visual studio. Пожалуйста, обратите внимание, что я только пробую это в Visual Studio 2015, это должно быть реализовано в C 98 для mbed в конце, что означает, что я не могу использовать std::next , например.

Комментарии:

1. Обратите внимание, что вы можете использовать C 11 с Mbed OS через пользовательский профиль сборки , который вы можете установить -std=c 11 .

Ответ №1:

std::copy() не будет создавать новые элементы в контейнере назначения. Это означает, что вам нужно создать destVect с правильным размером:

 vector<int> sourceVect = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
vector<int> destVect(sourceVect.size() - 1);
  

Если вы не можете создать его с правильным размером, просто измените его размер позже, в точке, где вы знаете размер:

 destVect.resize(sourceVect.size() - 1);
  

Теперь вы можете копировать:

 copy(sourceVect.begin()   1, sourceVect.end(), destVect.begin());
  

Однако вы можете просто создать destVect с правильным содержимым для начала. Вам не нужно ничего копировать вручную:

 vector<int> sourceVect = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
vector<int> destVect(sourceVect.begin()   1, sourceVect.end());
  

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

Комментарии:

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

2. @TrybGhost В таком случае просто используйте resize() . Обновлен ответ.

Ответ №2:

vector::iterator всегда поддерживал , вам не нужен next or advance . Самый простой способ — инициализировать из пары итераторов.

  std::vector<int> sourceVect = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
 std::vector<int>::iterator first = sourceVect.begin()   1;
 std::vector<int>::iterator last = first   numToCopy;
 std::vector<int> destVect(first, last); // contains 2,3,4,5,6,7,8
  

Если вы не можете избежать задержки объявления destVect до того момента, когда у вас появится соответствующий инициализатор, вы можете использовать assign

  destVect.assign(first, last); // contains 2,3,4,5,6,7,8 overwriting whatever was there before