I keep getting the error: no matching function for call to `std::vector<Menu_Item, std::allocator<Menu_Item> >::erase(int&)'
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
int item;
cout << "Please enter the menu item id you want to delete: \n";
cin >> item;
for (int i = 0; i < menu_items.size(); i++)
{
if(item==menu_items[i].item_id())
{
found = true;
Menu::menu_items.erase(i);
}
else
{
cout << "The ID number entered is wrong, please try again.\n";
}
}
}
What am I doing wrong? My vector is in Menu.h, which is called by Menu.cpp, which is run in my main().
This is a snippet from a program that I wrote a while back. 'character' is a class, 'it' is basically a pointer that pages through the list 'characters' to look at specific ones.
Using advance would be slightly more general then operator+. However, a better approach would be to use an iterator to traverse the collection rather than an int. That way, you'll already have the iterator handy. One word of caution, though: erasing an element from a vector invalidates iterators--you'd have to reassign the return value from the erase call to the iterator.
Untested example:
1 2 3 4 5 6
vector< int > v;
for( vector< int >::iterator i = v.begin(); i != v.end(); ++i ) {
/*if( something )*/ {.
i = v.erase( i );
}
}
@moorecm: Explain more about how it invalidates. If I were to, as you exampled, v.erase(i); would I be able to use the iterator still, assuming that I reset it to i = v.begin();?
Vectors guarantee contiguous storage for elements. When you remove one, the elements beyond it must be shifted to meet the guarantee. That means an iterater "pointing to" an element may no longer point to the right element. It becomes invalid. The erase method returns an iterator to the next valid element after the operation. It's a good thing that you asked because that also means that my example is flawed. The element after the one that was erased will now be skipped over because of the loops ++i. Here's a better example:
1 2 3 4 5 6 7 8 9
vector< int > v;
vector< int >::iterator i = v.begin();
while( i != v.end() ) {
if( /*something*/ ) {.
i = v.erase( i );
} else {
++i;
}
}
So if I understand you correctly, any iterators that are not corrected will be invalid, but if you're simply using an iterator to page through the vector repeatedly, then the erase won't have any effect on it, assuming that you don't skip the next iteration by incrementing during an erase.
Or, in other words, v.erase(iter);
causes v(iter-1), when it gets the command ++iter, to point to v(iter+1), instead of v(iter), which no longer exists, and the compiler automatically adjusts the value of iter to be the pointer of v(iter+1).
So if I understand you correctly, any iterators that are not corrected will be invalid
This is correct. You cannot make any assumptions about which element, if any at all, an iterator will refer to after it has been invalidated. When traversing a vector, you must reset the iterator to the return of the erase method to continue traversal.