In the first example, you will have to remove a and b , but not necessarily when units go beyond. You will usually do this just before units go out of scope, but this is not the only possible case. It depends on what is intended.
You can (later in the same function) an alias a or b , or both, because you want them to survive units or a scope of functions. You can put them in two unit objects at the same time. Or, many other possible things.
It is important that the destruction of the vector (automatic when the region is completed in this case) destroys the elements held by the vector, and nothing more. Elements are pointers, and killing a pointer does nothing. If you also want to destroy what the pointer points to (so as not to leak memory), you must do it manually ( for_each with lambda).
If you do not want to do this work explicitly, a smart pointer can automate this for you.
The second example (in the Edit1 section) does not require you to delete anything (in fact, this is not even possible, most likely you will see an attempt to do it), but this approach is probably harmful.
This code will work fine if you don’t refer to units anymore after a and b left pane. Woe, if so.
Technically, such a thing may even happen invisibly, since units destroyed after a , but, fortunately, ~vector does not look up pointer elements. It just destroys them, which does nothing for the pointer (trivial destructor).
But imagine that someone was so “smart” that they expanded the vector class, or maybe you will use this template in the future (because it “works fine”) with another object that does just that. Bang, you're dead. And you don’t even know where it came from.
What I really dislike about the code, even if it is strictly "legal", is the fact that it can lead to a condition that will lead to a failure or manifestation of a violation, irreproducible behavior. However, he is not immediately. The code that is “broken” should work immediately, so you see that something is wrong and you are forced to fix it. Unfortunately, this is not so.
It seems to work, perhaps for many years, until one day this happens. In the end, you forget that a and b live in the current frame of the stack and refer to non-existent objects in the vector from another place. Perhaps you are dynamically highlighting a vector in a future revision of your code, as you pass it to another function. And perhaps he will continue to work.
And then you will spend hours of your time (and probably others), trying to find out why a section of code that cannot fail leads to incorrect results or crashes.