templates - C++ map erase using forward and reverse iterators -
i have template function this
template<typename t> void foo(t start , t end) { while(start != end) { if(cond) m.erase(start); start++; } }
now have pass both forward , reverse iterator typename. 2 separate calls in 1 forward , 1 reverse iterator. how do ?
first of all, let me reiterate logicstuff's comment: should try pass in compatible iterators instead.
if really, really, really have no alternative doing way doing right now, use template functions:
#include <vector> #include <iostream> // used when both iterators have same type template <typename t> void foo(t begin, t end) { (; begin != end; ++begin) { std::cout << " " << *begin; } } // overload forward begin , reverse end template <typename t> void foo(t begin, std::reverse_iterator<t> end) { foo(begin, end.base()); } // overload reverse begin , 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; }
here convert reverse iterators forward iterators. this post gives more details that. read post carefully, there dragons. example above outputs numbers , not modify underlying container. , not check validity of iterators, nor do bounds checking. own case, make sure test edge cases (either iterator being @ or beyond beginning/end of container; off-by-one errors, etc.).
also, note in example code, call erase()
invalidates iterator, should write loop body this:
if (cond) { // guarantees return iterator element following // erased element. start = m.erase(start); } else { ++start; }
edit: if require iterators always converted forward equivalents, can change last overload , 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 aware order of iteration reversed: in example, calling foo(v.rbegin(), v.rend())
printed 9 8 7 ... 1
in first incarnation, , prints 1 2 3 ... 9
. example here.
and again, you'd off better if feed in compatible iterators instead.
Comments
Post a Comment