0

I have a quick question that's giving me some grief. As part of a much larger project, I want to scan a vector for elements that are 0 and, when I find them, delete them. I'm curious as to why the following is alright:

if (playerVec[5] == 0)

But this is not:

for(vector<Player>::iterator it = playerVec.begin(); it != playerVec.end(); ++it) {

if(playerVec[it] == 0) { //Invalid if condition

}

I assume it has to do with the factor that it is an iterator, but how else could I approach the deletion within a for loop? Do I need another variable for indexing?

3 Answers 3

2

it is an iterator, not an index. If you want to get the index from a (random access) iterator it, just do:

 it - playerVec.begin()

However, in your case you just want to dereference the iterator to get the value of the pointed element:

if (*it == 0) { 
    // ...
}
Sign up to request clarification or add additional context in comments.

7 Comments

Alright, mostly understood. The auto keyword is somewhat fuzzy to me, though I have heard of its use before. Is it strictly necessary in this case? If so, why?
@Rome_Leader: It is not strictly necessary, and in fact I edited the answer, because what I was suggesting was somewhat stupid. Please disregard it :)
Haha, fair enough! I have a feeling I will need to go elsewhere to overload the == operator though, since the compiler currently complains it has no definition for Player Type == Int Type. Am I right here?
I think is is not always right to compare a Player object with 0.(depends on how Player class is defined)
@ta.speot.is: lol, leftover from a previous attempt to cover more than I actually wanted to. I should definitely get some sleep and stop answering :)
|
2

You can use the remove_if function to remove elements within a container that meet some criteria:

#include <algorithm>

bool isZero(Player p) {
  return p == 0;
}

playerVec.erase(std::remove_if(playerVec.begin(), playerVec.end(), isZero),
                playerVec.end());

3 Comments

For this case, you can just use std::remove and pass the value 0. No need for a custom function. Also, in order to actually delete the elements from the container, you need to capture the return value of the algorithm and pass it to vector::erase.
Yeah, I definitely want the elements gone altogether. So erase seems to be the way to go. I think I can do that, still concerned about the condition for deletion, though
@Benjamin Thanks, I completely forgot about using erase.
1

Use the erase-remove idiom:

std::erase(std::remove(playerVec.begin(), playerVec.end(), 0), playerVec.end());

The reason your condition is invalid is because an iterator isn't an index. It's like a pointer to an element, and you can use it as such (with * and -> to access the element). For example, the correct condition in your code would be if(*it == 0).

2 Comments

I understand remove, but trying to wrap it in erase like you suggested gives a syntax error saying it is undefined. I have included both string and algorithm libraries, so I'm wondering what the issue is. EDIT: Actually, when I build it, the compiler throws an error then, even for the remove line itself. I have a feeling it's due to the multiple data member nature of Player.
Nvm, I got it with this, just needed to edit the syntax a little. Inside the outer brackets, after the remove operation, should be ,playerVec.end(). Thanks for the point in the right direction!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.