8

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.

3
  • 1
    The simple solution is to not manually manage your memory. If you really need pointers, use smart pointers. As you have a collection of pointers, though, if you want to compare the dereferenced pointers rather than the pointers themselves, you'll need to provide your own comparator to std::remove_if. Commented Oct 25, 2014 at 22:03
  • If you are sure that you need functionality that vector provides to you in your program then I would suggest you to change a data structure from std::vector<Object*> to std::map<int, Object*>. Commented Oct 25, 2014 at 22:06
  • @chris Yeah, I was using boost shared_ptrs but I've removed them back after reading a nice article. Besides, I just wanna do everything by myself 'cause I'm new at C++ and OOP and believe that this will bring on me better. I will look for std::remove_if Thanks. Commented Oct 25, 2014 at 22:11

4 Answers 4

15

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); } } 
Sign up to request clarification or add additional context in comments.

2 Comments

Oh come ooonn :) I feel so stupid just right now :) How didn't I try that without *? And I can't erase it by position because obj37 was just an assumption I couldn't know the position in my thing. myVec.erase(std::remove(myVec.begin(), myVec.end(), obj37), myvec.end()); working like a charm. Thank you so much.
For those who cannot get this compiled, don't forget to #include <algorithm>
3

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.

Comments

0

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.

Comments

-1

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.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.