First of all, let me reiterate LogicStuff's comment: You should really try to pass in compatible iterators instead.
If you really, really, really have no alternative to doing it the way you are doing it right now, you could use some template functions:
#include <vector>
#include <iostream>
// Used when both iterators have the same type
template <typename T>
void foo(T begin, T end)
{
for (; begin != end; ++begin)
{
std::cout << " " << *begin;
}
}
// Overload for a forward begin and reverse end
template <typename T>
void foo(T begin, std::reverse_iterator<T> end)
{
foo(begin, end.base());
}
// Overload for a reverse begin and forward end
template <typename T>
void foo(std::reverse_iterator<T> begin, T end)
{
foo(begin, std::reverse_iterator<T>(end));
}
int main()
{
std::vector<int> v { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
foo(v.begin(), v.end()); std::cout << std::endl;
foo(v.begin(), v.rbegin()); std::cout << std::endl;
foo(v.rbegin(), v.begin()); std::cout << std::endl;
foo(v.rbegin(), v.rend()); std::cout << std::endl;
}
See it running on ideone.
Here I convert reverse iterators to forward iterators. This SO post gives you more details about that. But read that post very carefully, there be dragons. My example above just outputs numbers and does not modify the underlying container. And I do not check the validity of the iterators, nor do I do any bounds checking. For your own case, make sure you test all the edge cases (either iterator being at or beyond the beginning/end of your container; off-by-one errors, etc.).
Also, note that in your example code, the call to erase()
invalidates the iterator, so you should write the loop body like this:
if (cond) {
// guarantees to return an iterator to the element following
// the erased element.
start = m.erase(start);
} else {
++start;
}
Edit: If you require that iterators are always converted to their forward equivalents, you can change the last overload and add another:
template <typename T>
void foo(std::reverse_iterator<T> begin, T end)
{
foo(end, begin.base()); // Note: order of iteration reversed!
}
template <typename T>
void foo(std::reverse_iterator<T> begin, std::reverse_iterator<T> end)
{
foo(end.base(), begin.base()); // Note: order of iteration reversed!
}
But be aware that the order of iteration is now reversed: in my example, calling foo(v.rbegin(), v.rend())
printed 9 8 7 ... 1
in the first incarnation, and now it prints 1 2 3 ... 9
. Example here.
And again, you'd be off much better if you could feed in compatible iterators instead.