RemoveByName__CLASSIC__NOT_OK
executes undefined behavior.
When you erase from a std::vector
, all iterators and references to elements at or after the point of erasure are invalidated. That means they cannot be dereferenced or compared or anything else but overwritten safely without invoking undefined behavior.
Now, UB is often "does the thing you thought it should do magically", so a failure to crash doesn't help you.
As it happens, if RemoveByName__CLASSIC__NOT_OK
did a break
immediately after the erase
, it would be well defined.
RemoveByName__CLASSIC__OK
defers the erase until after you finish the iteration. It has a number of problems, including executing undefined behavior if an element with that name is not there, not handling duplicate names, etc. It erases the last element matching the name if it exists, and otherwise does undefined behavior. You probably want every element, and/or erase the first you find to save time. (If you really want last, iterate backwards and erase the first you find).
.reset()
prior to destroying a shared_ptr
moves the possible destruction of the object to the .reset()
instead of it being inside the guts of std::shared_ptr
, which sometimes can be useful (as any and all access to std::vector
while you are in the guts is UB). One thing I oftne do is swap
or move
the shared_ptr
out of the container, .erase
it from the container, then .reset
or just let the local shared_ptr
copy go out of scope.
Your RemoveByName__PREDICATE__OK
is also broken and can exhibit undefined behavior and basically does the wrong thing if anything except 1 element matching the predicate is found. Change the );
at the end of the erase
clause to , resourceList.end());
, so that instead of erasing one element it erases everything from the return value of remove_if
to the end of the vector
.