简体   繁体   中英

way to remove an object from a vector?

I am struggling to remove a custom type from a vector. I have the following code:

#include "pch.h"
#include <iostream>
#include <vector>

class Account {
public: 
    std::string name;
    int balance; 
};

int main()
{
    std::vector<Account> holding_vector;
    Account new_acc1;
    Account new_acc2;
    Account new_acc3; 
    holding_vector.push_back(new_acc1);
    holding_vector.push_back(new_acc2);
    holding_vector.push_back(new_acc3);

}

How would I go about removing new_acc2 ? The only real idea can think of is to try and overwrite one of the class' operators so that the find() algorithm can locate the object in the vector?

Arrrg 1991 again.

The first thing I just want to clarify is that new_acc2 is not in the vector. A copy of the variable new_acc2 was created in the vector.

The trouble is that new_acc1 , new_acc2 and new_acc3 all have the same value (basically no name and a zero balance). So when you placed them into the vector you got three copies of basically the same object. So how do you know which one you want to remove (they are all the same).

To remove something from a vector you should be able to uniquely identify it. So lets assume you gave each account a new unique name when you add it to the vector.

    holding_vector.push_back(Account{"Bob", 10});
    holding_vector.push_back(Account{"Mary", 20});
    holding_vector.push_back(Account{"John", 40});

Now you want to remove "John"'s account. Then you can use the erase method.

    // first you have to find a reference to the object you want
    // to remove.
    auto find = std::find_if(std::begin(holding_vector), std::end(holding_vector),
                             [](auto const& a){return a.name == "John";});

    // If you found the item then you can remove it.
    if (find != std::end(holding_vector)) {
        holding_vector.erase(find);
    }

Note: Above we had to use a specialized Lambda to tell the code how to check for a named account called "John". But you can make it easier by allowing the object to simply be compared against a string.

class Account {
    public: 
        std::string name;
        int balance; 

        bool operator==(std::string const& test) const {return name == test;}
    };

Now you can simplify the above with the following erase:

    // first you have to find a reference to the object you want
    // to remove.
    auto find = std::find(std::begin(holding_vector), std::end(holding_vector), "John");

    // If you found the item then you can remove it.
    if (find != std::end(holding_vector)) {
        holding_vector.erase(find);
    }

Use std::find_if to find an element that matches a given criteria. Then use vector::erase to delete that element.

What the criteria is depends on your requirements, which are hard to guess with the code posted.

If, for example, you wanted to remove accounts with a certain name you can find them in this way;

auto it = std::find_if(std::begin(holding_vector), std::end(holding_vector), [](Account const& acc) { return acc.name == "some_account_name"; });

If multiple items could match the same criteria, and you want to remove them all (and not just the first one), then I would suggest the erase-remove idiom. There are already answers on stackoverflow to help with that.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM