Reputation:
In the bellow example code after assigning example list with numbers I'm trying to duplicate container with std::copy
but problem is at runtime it says "cannot dereference end list iterator".
my question is how do I duplicate the list so that duplicated range is inserted to the end of the list?
to the end because I later need to be able to remove duplicated range, that is why I save the beginning of the new range to iterator.
#include <iostream>
#include <list>
#include <algorithm>
void print(std::list<int>& ref)
{
for (auto& 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;
}
Upvotes: 4
Views: 97
Reputation: 38315
You can use std::copy_n
. This circumvents the issue with std::copy
, which would execute an infinite loop of insertions when fed with a std::back_inserter(mylist)
and an always valid mylist.end()
iterator.
const std::size_t n = mylist.size();
std::copy_n(mylist.cbegin(), n, std::back_inserter(mylist));
De-duplication then works with
mylist.erase(std::next(mylist.begin(), n), mylist.end());
Upvotes: 2
Reputation: 8475
if (!mylist.empty()) --iter;
std::copy_n(mylist.begin(), mylist.size(), std::back_inserter(mylist));
if (!mylist.empty()) ++iter;
Unfortunately we can't use end iterator in copy(), since it might lead to an infinite loop, as new elements are added between the end and the current iterator all the time.
Upvotes: 1