lsch91
lsch91

Reputation: 335

C++ How to delete a specific object in a vector?

I'm trying to figure out how to delete a specific object in a vector. I'm searching the vector based on a string named id. Hoping someone can help me fill in the blanks! Thanks! Is the way i'm erasing valid??

my vector is like this:

 vector<member*> memb;

and this is what i have so far:

for (int i = 0; i < memb.size(); i++)
{
    if( std::find(memb.begin(),memb.end(), id) != memb.end() ) {
        myvector.erase (memb.begin(),memb.begin()=id);
    }
} 

Upvotes: 1

Views: 2114

Answers (2)

l2m2
l2m2

Reputation: 453

    vector<member *>::iterator iter;
    for (iter=memb.begin(); iter!=memb.end();) {
        if ((*iter)->id == id) {
            delete (*iter);
            iter = memb.erase(iter);
        } else {
            iter++;
       }
    }

Upvotes: 0

Remy Lebeau
Remy Lebeau

Reputation: 596352

Get rid of your loop. std::find() (and std::find_if()) does the necessary looping for you.

std::find() (and std::find_if()) returns an iterator to the element if found, or the specified last iterator if not found. If the element is found, pass the returned iterator to the vector's erase() method to remove the element.

Since you are storing pointers in your vector, you cannot use std::find() to search by a std::string value. You need to use std::find_if() instead.

Try this:

struct isID
{
    const std::string &m_id;

    isID(const std::string &id) : m_id(id) {}

    bool operator()(const member *m) const
    {
        return (m->id == m_id);
    }
};

std::string id = ...;

std::vector<member*>::iterator iter = std::find_if(memb.begin(), memb.end(), isID(id));
if (iter != memb.end())
{
    // since you are storing pointers in the vector, you
    // need to free the object being pointed at, if noone
    // else owns it...

    //delete *iter;
    memb.erase(iter);
}

Or, if you are using C++11 or later:

std::string id = ...;

auto iter = std::find_if(memb.begin(), memb.end(),
                [id](const member* m) { return (m->id == id); } );
if (iter != memb.end())
{
    // since you are storing pointers in the vector, you
    // need to free the object being pointed at, if noone
    // else owns it...

    //delete *iter;
    memb.erase(iter);
}

In the latter case, if the vector is intended to own the objects, you can store std::unique_ptr objects in the vector to automatically free the member objects for you:

std::vector<std::unique_ptr<member>> memb;

...

std::unique_ptr<member> m(new member); 
// or: std::unique_ptr<member> m = std::make_unique_ptr<member>(); 
memb.push_back(std::move(m));

// or: memb.push_back(std::unique_ptr<member>(new member)); 
// or: memb.push_back(std::make_unique<member>()); 
// or: memb.emplace_back(new member); 

...

if (iter != memb.end())
{
    // std::unique_ptr will free the object automatically
    // when the std::unique_ptr itself is destroyed...

    memb.erase(iter);
}

Upvotes: 4

Related Questions