Стандарт не совсем прописан, но v.erase(q) определен, "Стирает элемент, на который указывает q" в [sequence.reqmts]. Это означает, что q должен фактически указывать на элемент, который итератор конца не делает. Передача в конце итератора - это поведение undefined.
К сожалению, вам нужно написать:
auto it = std::find(...);
if (it != <the part of ... that specifies the end of the range searched>) {
v.erase(it);
}
c.erase() в ассоциативном контейнере возвращает void, поэтому, чтобы обобщить этот шаблон на все контейнеры, вам нужно какое-то действие -> decltype.
Ответ 2
Стирание end() (или, если на то пошло, даже глядя на цель end()), это поведение undefined. Поведение undefined допускает любое поведение, включая "просто работу" на вашей платформе. Это не значит, что вы должны это делать; это по-прежнему undefined поведение, и я буду укусить вас наихудшими способами, когда вы меньше всего этого ожидаете.
В зависимости от того, что вы делаете, вы можете рассмотреть set или unordered_set вместо vector здесь.