Reputation: 335
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
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
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