allyozturk
allyozturk

Reputation: 117

How to erase vector element by pointer?

I have this:

vector<Object*> myVec;

and adding my objects to it like this:

Object *obj1 = new Object;
myVec.push_back(obj1);

Let's assume that I have 100 objects in this way and pointers going as *obj1, *obj2 ... *obj100.
And now I want to remove let's say, obj37, from the vector. I wish I could do that just like pushing it:

myVec.remove_back(obj37);

It would be awesome if there was a function like "remove_back" but there is not I think. I hope you got the point and please help me about that.

By the way, just look at this question, in accepted answer, there is remove algorithm works by value:

vec.erase(std::remove(vec.begin(), vec.end(), 8), vec.end());

I gave it a shot that with pointer even I didn't believe that would work and surprise; it didn't:

myVec.erase(std::remove(myVec.begin(), myVec.end(), *obj37), vec.end());

Yeah, I know that I've just bullshit but that's for you got the point. Somewhere there should be a simple solution like this and I just want that.

Upvotes: 8

Views: 24817

Answers (4)

prok_8
prok_8

Reputation: 329

As stated in the GNU C++ library documentation, chapter 10 (here)

Since iterators are a generalization, that means that pointers are iterators, and that pointers can be used whenever an iterator would be. All those functions in the Algorithms section of the Standard will work just as well on plain arrays and their pointers.

Since by already having a pointer to the element, it's not necessary to search for it by value via std::find or std::remove. Casting the pointer to the iterator type will work.

std::vector<int> vec = { 1, 2, 3, 4, 5 };
int* ptr = &vec[2];
vec.erase(static_cast<std::vector<int>::iterator>(ptr));

Value of vec after code execution: { 1, 2, 4, 5 }.

EDIT:

If you have a const pointer, you must instead cast to std::vector<T>::const_iterator.

Upvotes: 0

Mosa
Mosa

Reputation: 393

If you use C++11 you can put smart pointers into your vector. Than you can use the erase-method to remove the object and automaticly the smart pointer handles the delete pointer stuff.

vector<std::shared_ptr<Object>> myVec;

The shared_ptr has a reference rounter inside. If the object is not referenced by any variable it will be delete automaticly.

Upvotes: -1

Kerrek SB
Kerrek SB

Reputation: 476950

You're almost there: Search the element by value:

myVec.erase(std::remove(myVec.begin(), myVec.end(), obj37), myvec.end());
//                                                  ^^^^^

Alternatively, if you know that the element is in position 36 (0-based), you can erase it directly:

myvec.erase(myvec.begin() + 36);

Or, in modern C++:

myvec.erase(next(begin(myvec), + 36));

Also note that std::remove searches the entire vector, so if you know that there is only one element, you can use find instead to stop as soon as you find the value:

{
    auto it = std::find(myVec.begin(), myVec.end(), obj37);
    if (it != myVec.end()) { myVec.erase(it); }
}

Upvotes: 15

Dietmar K&#252;hl
Dietmar K&#252;hl

Reputation: 153802

std::remove() "removes" the values matching the last argument. That is, you can remove your pointer like this:

myVec.erase(std::remove(myVec.begin(), myVec.end(), ptr), myVec.end());

If there is just one element matching it may be easier to use std::find() instead of std::remove(). If you actually want to match the pointed to value you'd use the _if version of the algorithm with a suitable predicate. Of course, removing the pointer won't release any memory.

Upvotes: 3

Related Questions