user11157650
user11157650

Reputation:

Duplicating std::list with std::copy and removal with std::list::erase

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

Answers (2)

lubgr
lubgr

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

Michael Veksler
Michael Veksler

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

Related Questions