How to erase elements from a vector specified by an iterator list?

I have an int vector and a mapping that contains some iterators pointing to the vector as values. I need to remove the keys from the map and the vector element that the value points to. My code looks briefly:

using RenderData = int;
using Element = std::string;

struct Ref {
    std::vector<RenderData>::iterator ref;
    std::function<int()> update;
    bool should_remove;
};

int main() {
    std::vector<RenderData> ints{1, 2, 3, 4, 5, 6, 7, 8, 9};
    std::unordered_map<Element, Ref> elements;

    // Here, I need to remove some elements, and their associated number
}

I implemented a function erase_ifthat looked like this .

So my initial code looked like this:

erase_if(elements, [&](auto&& element) {
    if (element.second.should_remove) {
        ints.erase(element.second.ref);
        return true;
    }

    return false;
});

That obviously didn't work. The erasing element causes another iterator to point to the wrong object, and in some cases to the anchor. So I tried this:

std::vector<std::vector<RenderData>::iterator> to_remove;

erase_if(elements, [&](auto&& element) {
    // condition based on the string content
    if (element.second.should_remove) {
        to_remove.emplace_back(element.second.ref);
        return true;
    }

    return false;
});

// Sort in descending order
std::sort(to_remove.begin(), to_remove.end(), std::greater<>{});

// stuff

for (auto&& it : to_remove) {
    ints.erase(it); // nothing can go wrong right?
}

And again, I sometimes erased the wrong elements.

Given that iterators stored on a map can you remove elements pointed to by iterators from a vector?


Update:

, , . , , .

+4
3

. :

  • .
  • , , .
  • - , , .

: ,

using Element = std::string;
using RenderData = int;
struct Ref {
    std::vector<RenderData>::iterator itr;
    bool should_remove;
};

struct Main {
    std::vector<RenderData> ints;
    std::unordered_map<Element, Ref> elements;
    void remove_stuff(){
        std::vector<RenderData> localCopy;        
        localCopy.swap(ints);
        ints.reserve(localCopy.size());        
        for(auto it = elements.begin(); it != elements.end();) {
            Ref& ref = it->second;
            if(ref.should_remove) {
                it = elements.erase(it);
            } else {
                ints.push_back(std::move(*ref.itr));
                ref.itr = ints.end() - 1;                
                it++;
            }
        }            
    }
};

: https://godbolt.org/g/SouZ5E

+1

A: std::vector std:: list, std:: list .

B:

std::vector<int> newOne;
copy_if(oldOne.begin(), oldPOne.end(), std::back_inserter(newOne), [](){ //to test not in the map ~~ });
oldOne = std::move(newOne)
+1

.

struct Ref {
    std::vector<RenderData>::iterator ref;
    std::function<int()> update;
    bool should_remove;
};
std::vector< std::vector<RenderData>::iterator> to_remove;

struct Ref {
    std::size_t ref;
    std::function<int()> update;
    bool should_remove;
};
std::vector< std::size_t> to_remove;

. ints.erase(ints.begin() + ref)

- . , . , , //.

(iterator pos); ( ++ 11)

(const_iterator pos); ( ++ 11)

pos.

, end().

+1

Source: https://habr.com/ru/post/1692609/


All Articles