c++iteratorerasestdmove

How to erase an element from a vector using a std::move_iterator?


This is a Josephus Permutation problem, it was solved by using std::move(), but now I have to switch to using std::move_iterator (by using std::make_move_iterator()) However, this doesn't compile:

template <typename RandomIt>
void MakeJosephusPermutation(RandomIt first, RandomIt last, uint32_t step_size) {
    list<typename RandomIt::value_type> pool;
    for (auto it = make_move_iterator(first); it != make_move_iterator(last); ++it) {
        pool.push_back(*it);
    }
    auto cur_pos = make_move_iterator(pool.begin());
    while (!pool.empty()) {
        *(first++) = *cur_pos;
        if (pool.size() == 1) {
            break;
        }
        const auto next_pos = LoopIterator(pool, next(cur_pos));

        pool.erase(cur_pos); //-> *"No matching member function for call to 'erase'"

        cur_pos = next_pos;
        for (uint32_t step_index = 1; step_index < step_size; ++step_index) {
            cur_pos = LoopIterator(pool, next(cur_pos));
        }
    }
}

I haven't been able to find info on this on cppreference, how can you remove the element from the vector in this case? I.e. I know that the element will have been moved, but not having some sort of "erase" there messes up the algorithm...


Solution

  • std::list<T>::erase() takes an argument of type std::list<T>::const_iterator or std::list<T>::iterator. See: https://en.cppreference.com/w/cpp/container/list/erase

    You are trying to call erase with parameter of type std::move_iterator<Iter>, but there is no support for converting it into one of the list iterator types: https://en.cppreference.com/w/cpp/iterator/move_iterator

    You should access the base iterator to call erase:

    pool.erase(cur_pos.base());