obtaining the index of a vector iterator

in the member function, i dont really care what the position is i just want to get the index of the iterator as to delete it as i have already "found" the object in the vector that i want to delete by the if condition.

The problem is not deleting it, the error i get is the display() member function. apparently I am sending in the iterator of the vector and not the actual object in the vector which the member function display() is set to receive as an argument? I think i might of got that right?

If i did, how do I send in the object and not the iterator?

So instead of overloading the member function display() to take in an iterator, how can i adapt it to just the object of the vector?

1
2
3
4
5
6
7
8
void Control::kill_old_update(){
    for (std::vector<Bunny>::iterator it = bunny_obj_list.begin(); it != bunny_obj_list.end(); ++it){
        if(it->age > age_to_die){
            display(it, "old");
            bunny_obj_list.erase(it);
        }
    }
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
void Control::display(Bunny object, std::string reason){
    std::string display_reason;
    std::string display_string;
    std::string disp_RA;
    if (reason == "born")
        display_reason = "was born.";
    else if (reason == "old")
        display_reason = "has died of old age.";
    else if (reason == "RA")
        display_reason = "was killed by radiation.";

    if (object.get_RA()){
        disp_RA = "Radioactive ";
    }
    else{
        disp_RA = "";
    }

    display_string =  disp_RA + "bunny " + object.get_name() + " " + display_reason + "\n" + object.get_sex() + " " + object.get_color();
    cout << display_string <<endl;


    sleep(1);
}


error:
/home/metulburr/Documents/cplusplus/radioactive_bunnies/src/Control.cpp|73|error: no matching function for call to ‘Control::display(std::vector<Bunny>::iterator&, const char [4])’|
Last edited on
To call display with a Bunny as the first argument, just call display(*it, "old"):

However, keep in mind that the loop in kill_old_update() won't work as written: the call to erase() invalidates the iterator. Control::kill_old_update() should call remove_if() or some other algorithm since you want to do things to the old bunnies first (partition perhaps) followed by erase(), it has no business dealing with iterators on its own.
(edit: yes, using the return value of vector::erase() would make this work too)
Last edited on
First of all this function is invalid

1
2
3
4
5
6
7
8
void Control::kill_old_update(){
    for (std::vector<Bunny>::iterator it = bunny_obj_list.begin(); it != bunny_obj_list.end(); ++it){
        if(it->age > age_to_die){
            display(it, "old");
            bunny_obj_list.erase(it);
        }
    }
}


Shall be

1
2
3
4
5
6
7
8
9
10
11
12
void Control::kill_old_update(){
    for (std::vector<Bunny>::iterator it = bunny_obj_list.begin(); it != bunny_obj_list.end(); ){
        if(it->age > age_to_die){
            display(it, "old");
            it = bunny_obj_list.erase(it);
        }
        else
        {
                ++it;
        ]
    }
}


Secondly function display shall be called as

display(*it, "old");
just as i think i am starting to get the hang of it...ugh. lol they do not lie when they say c++ is harder than python, so to speak.

the call to erase() invalidates the iterator

im not sure what you mean by that.

I thought it was as follows:
//loop through the indexes of the vector
//if index.age > age_to_die
//display(index, "some_string")
//vector.erase(index)
1
2
3
4
    for (std::vector<Bunny>::iterator it = bunny_obj_list.begin(); it != bunny_obj_list.end(); ++it){
        if(it->age > age_to_die){
            display(it, "old");
            bunny_obj_list.erase(it);


(partition perhaps)

I also am not sure what you mean by partition?

since you want to do things to the old bunnies first

so this would be the proper method if i was just deleting the object and not doing anyhting with it within the for loop?

not sure what you mean by partition?

The C++ function std::partition(), you could use it to split the bunnies into old and not so old. There are really many things that can be done.

the proper method if i was just deleting the object and not doing anyhting with it within the for loop?

That would be

1
2
3
4
5
6
void kill_old_update() {
    bunny_obj_list.erase(
        std::remove_if( bunny_obj_list.begin(), bunny_obj_list.end(),
            [&](const Bunny& b){ return b.age > age_to_die; } ),
        bunny_obj_list.end() );
}

(this uses the ubiquitious erase-remove idiom)
[&](const Bunny& b){ return b.age > age_to_die; } ),

The reference here is unnecessary.

Edit: I am sorry. I thought that the second operand is also of type Bunny.:) That is that the two operands are parameters of the lambda expression.
Last edited on
The C++ function std::partition(), you could use it to split the bunnies into old and not so old

would this matter only if i was deleting the vector objects by age, because i plan on making other member functions which will delete the same vector of objects by bool RA value, by age, by population number, by a number of other things too. Which would organizing them into a partition ordered by age moot?

1
2
3
4
5
6
void kill_old_update() {
    bunny_obj_list.erase(
        std::remove_if( bunny_obj_list.begin(), bunny_obj_list.end(),
            [&](const Bunny& b){ return b.age > age_to_die; } ),
        bunny_obj_list.end() );
}

I am not even sure how to respond to that as i dont know what is going on with that segment of code:

I think it reorders the if into the remove_if()?

If so, wouldnt the if condition be more clear as to what is going on with the segment of code?
When a C++ programmer encounters x.erase(remove_if(x.begin(), x.end(), condition), x.end()), this is instantly clear what's going on (every element for which the condition is true is erased).

The loop is more-or-less recognizable too (after vlad's correction of course), but it it has more moving parts to look at and it's a whole lot slower.

There are a few different ways to write the condition for remove_if, of course, classic (1998) approach was to write something like

1
2
3
4
5
void kill_old_update() {
    bunny_obj_list.erase(
        std::remove_if( bunny_obj_list.begin(), bunny_obj_list.end(), OlderThan(age_to_die) ),
        bunny_obj_list.end() );
}
which can be quite readable given a well-named functor, but it requires a few more lines somewhere earlier defining it.
Last edited on
ah ok.
Thanks

I am still trying to convert myself from Python to c++, and i get lost in the syntax of C++ at times. Plus there are so many methods in the reference of each library, its hard to remember them all, well for me its hard to remember a few.
Last edited on
Topic archived. No new replies allowed.