#c #list #copy
#c #Список #Копировать
Вопрос:
В приведенном ниже примере кода после присвоения примера списка с номерами я пытаюсь дублировать контейнер с помощью std::copy
но проблема в том, что во время выполнения он говорит «не удается разыменовать итератор конечного списка».
мой вопрос в том, как мне дублировать список, чтобы дублированный диапазон был вставлен в конец списка?
до конца, потому что позже мне понадобится возможность удалять дублированный диапазон, поэтому я сохраняю начало нового диапазона в iterator.
#include <iostream>
#include <list>
#include <algorithm>
void print(std::list<int>amp; ref)
{
for (autoamp; num : ref)
{
std::cout << num << std::endl;
}
}
int main()
{
std::list<int> mylist{ 1, 2, 3, 4 };
std::list<int>::iterator iter = mylist.end();
std::cout << "INITIAL LIST NUMBERS" << std::endl;
print(mylist);
// duplicate list, will cause runtime error
iter = std::copy(mylist.begin(), mylist.end(), --mylist.end());
std::cout << "COPIED LIST IS NOW CONTAINS DUPLICATE NUMBERS" << std::endl;
print(mylist);
// remove previsous duplication
mylist.erase(iter, mylist.end());
std::cout << "AFTER REMOVAL OF COPIED LIST SHOULD BE SAME AS INITIAL LIST" << std::endl;
print(mylist);
std::cin.get();
return 0;
}
Ответ №1:
Вы можете использовать std::copy_n
. Это позволяет обойти проблему с std::copy
, которая выполняла бы бесконечный цикл вставок при подаче с std::back_inserter(mylist)
и всегда действительным mylist.end()
итератором.
const std::size_t n = mylist.size();
std::copy_n(mylist.cbegin(), n, std::back_inserter(mylist));
Удаление дублирования затем работает с
mylist.erase(std::next(mylist.begin(), n), mylist.end());
Комментарии:
1. Это сработало, вы не знаете, возможно ли это сделать с помощью std:: copy?
2. std::copy_n, std::next() и size() определенно являются ключом к решению этой проблемы!
Ответ №2:
if (!mylist.empty()) --iter;
std::copy_n(mylist.begin(), mylist.size(), std::back_inserter(mylist));
if (!mylist.empty()) iter;
К сожалению, мы не можем использовать конечный итератор в copy(), поскольку это может привести к бесконечному циклу, поскольку между конечным и текущим итераторами постоянно добавляются новые элементы.
Комментарии:
1. несмотря на то, что ваше решение эквивалентно решению lubgr, я пометил его ответ, потому что std:: next() выглядит более удобным для чтения, спасибо за понимание
2. @zebanovich обратите внимание, что next (begin, n) — это O (n). Это решение выглядит лучше, но может быть на 30% медленнее (с учетом затронутых узлов)