Is there a way to iterate over a priority queue in c++ ? My understanding is that they are more or less immutable and the only manipulation of the container is to the top element. I would like to be able to print out the contents of a priority queue but am unsure of how to even approach the problem.
The underlying container is a protected data member named c (see here for further details). Therefore you can always inherit from a std::priority_queue and export a couple of iterators over that container (if available).
As a minimal, working example:
#include<queue>
#include<iostream>
struct MyPriorityQueue: std::priority_queue<int> {
auto begin() const { return c.begin(); }
auto end() const { return c.end(); }
};
int main() {
MyPriorityQueue pq;
pq.push(0);
pq.push(1);
for(auto &v: pq) {
std::cout << v << std::endl;
}
}
Note: inheriting from data structures in the std:: namespace is usually discouraged.
That being said, it works at least.
The code above works in C++14.
Below a slightly modified version that works also in C++11 as requested in the comments:
#include<queue>
#include<iostream>
struct MyPriorityQueue: std::priority_queue<int> {
decltype(c.begin()) begin() const { return c.begin(); }
decltype(c.end()) end() const { return c.end(); }
};
int main() {
MyPriorityQueue pq;
pq.push(0);
pq.push(1);
for(auto &v: pq) {
std::cout << v << std::endl;
}
}
Based on #skypjack's answer, here is a templated version:
#include<queue>
#include<iostream>
template<class T, class C = vector<T>, class P = less<typename C::value_type> >
struct MyPriorityQueue :
std::priority_queue<T,C,P> {
typename C::iterator begin() { return std::priority_queue<T, C, P>::c.begin(); }
typename C::iterator end() { return std::priority_queue<T, C, P>::c.end(); }
};
int main() {
MyPriorityQueue<int> pq;
pq.push(0);
pq.push(1);
for (auto &v : pq) {
std::cout << v << std::endl;
}
}
Related
I would like to find a clean way to slightly change the way std::vector operates.
Problem background
I need to be able to have index in the vector where the pointer would essentially slip one back, so for example; if my vector contains {0,1,2,3,4,5} and index [3] needs to slip, when iterating through the vector it should return: 0, 1, 2, 3, 3, 4, 5
Problem
Without rewriting the entire vector class and implementing my changes, is it possible to inherit std::vector<T> into a custom class, and override the behavior of the iterators ++ operator as well as the vector::begin()? (to add memory of the fact that it has already slipped one and not to slip again)
What I have tried
I have tried a basically implementation so far, but have gotten stuck when trying to override the begin() function.
#include <vector>
#include <iostream>
#include <iterator>
template <typename T>
class myVector : public std::vector<T>{
public:
class myIterator : public std::vector<T>::iterator
{
// call vector's iterotor constructor
//override
// iterator& operator++(void){}
// iterator operator++(int){}
};
using std::vector<T>::vector; // use the constructor from vector
// extend the begin function, but include original operation
myVector::myIterator begin() const
{
std::cout << "hi\n"; // testing to see if begin has been overriden properly
return std::vector<T>::begin();
}
};
// print out the vector
template <typename T>
std::ostream& operator<<(std::ostream& os, const myVector<T>& v)
{
auto begin=v.begin();
while (begin!=v.end())
{
os << *begin;
++begin;
if(begin!=v.end())
{
os << ',';
}
}
return os;
}
int main() {
myVector<int> vec = {1,2,3,4};
std::cout << vec << '\n';
}
If you have an alternative clean solutions, it is also welcome.
Thanks
I would never inherit from std::vector publicly. It is just too easy to be used wrong and you have no control over misuse. std::vector has no virtual destructor!
Iterators seems to be the appropriate customization point. Much more is needed to get a fully compliant iterator, but this is enough for a working example:
#include <iterator>
#include <vector>
#include <iostream>
template <typename It>
struct slippery_iterator {
bool slipped = false;
It to_be_repeated;
It iterator;
slippery_iterator(It iterator,It to_be_repeated) : iterator(iterator),to_be_repeated(to_be_repeated){}
slippery_iterator& operator++(){
if (!slipped && iterator == to_be_repeated){
slipped = true;
return *this;
}
++iterator;
return *this;
}
typename std::iterator_traits<It>::reference operator*(){
return *iterator;
}
bool operator!=(It other) { return iterator != other;}
};
template <typename It>
slippery_iterator<It> make_slippery_iterator(It it,It slip){
return {it,slip};
}
int main() {
std::vector<int> x{1,2,3,4,5};
auto begin = make_slippery_iterator(x.begin(),x.begin()+2);
for (; begin != x.end(); ++begin){
std::cout << *begin;
}
}
Output:
123345
PS: Note that I am used to C++11 where you need a make_x helper. It isnt needed with more recent standards.
As others already said, just define a custom iterator. If you moreover want the nice range iteration, you can then just define a custom range class returning your custom iterators.
See a working example below (needs --std=c++17):
#include <vector>
#include <iostream>
template<typename T>
class SlipIterator {
private:
using iterator = typename std::vector<T>::const_iterator;
iterator i;
iterator slip;
bool has_slipped;
public:
SlipIterator(iterator i, iterator slip): i(i), slip(slip), has_slipped(false) {}
SlipIterator &operator++() {
if ((!has_slipped) && (i == slip))
has_slipped = true;
else
++i;
return *this;
}
bool operator!=(SlipIterator<T> &the_end) const { return i != the_end.i; }
const T &operator*() const { return *i; }
};
template<typename T>
class SlipperyRange {
private:
const std::vector<T> &v;
size_t slip_index;
public:
SlipperyRange(const std::vector<T> &v, size_t slip_index) : v(v), slip_index(slip_index) {}
SlipIterator<T> begin() const { return SlipIterator<T>(v.cbegin(), v.cbegin() + slip_index); }
SlipIterator<T> end() const { return SlipIterator<T>(v.cend(), v.cend()); }
};
int main() {
std::vector<int> v{1,2,3,4,5};
for(const int i: SlipperyRange{v, 2})
std::cout << i << ' ';
std::cout << '\n';
return 0;
}
I want to provide an iterator that iterates over contents of 2 containers.
For example, I would like to hide the fact that the nodes of a polyline are stored in two containers (for implementation purposes):
struct PolyLine {
private:
vector<Point*> m_head_nodes;
vector<Point*> m_tail_nodes;
public:
Iterator begin();
Iterator end();
};
Polyline poly;
cout << "contents of poly:" << endl;
for(Point *p : poly)
cout << p << endl;
The iterator should iterate the m_head_nodes first, then the m_tail_nodes.
Q1: Could you demonstrate how to set up the Iterator object?
How do you implement the operator++ at the point where you cross from the first container to the second?
Q2: what if, say the 2nd container was, say, a std::list ?
What construct do you use to represent the current 'position' iterator?
How do you represent the end() ?
I have tried an implementation like the following,
struct Iterator
{
PolyLine &m_parent;
vector<Point*>::iterator m_it;
Iterator(PolyLine &parent_container)
: m_parent(parent_container) {
}
Iterator& operator++() {
if (m_it == m_parent.m_head_nodes.end())
m_it = m_parent.m_tail_nodes.begin();
else
++m_it;
return *this;
}
Point * operator* () {
return *m_it;
}
};
bool operator== (Iterator &one, Iterator &other) {
return one.m_it == other.m_it;
}
Iterator Polyline::begin() {
Iterator o(this);
o.m_it = m_head_nodes.begin();
return o;
}
Iterator Polyline::end() {
Iterator o(this);
o.m_it = m_tail_nodes.end();
return o;
}
but I am not keen on keeping a pointer to the PolyLine class.
Plus, I don't know what to keep as an m_it in case the 2nd container is a, say, std::list.
Does something like this work for you (obviously it's a bashed out in 10 min kinda solution so don't expect the committee to insta-ship it in c++20 or something lol - it's just to give some ideas):
#include <iostream>
#include <array>
#include <vector>
#include <deque>
#include <algorithm>
template<typename Pointee0, typename Pointee1, typename It0, typename It1> struct ChainedIter;
template<typename Pointee, typename It0, typename It1>
class ChainedIter<Pointee, Pointee, It0, It1> {
It0 it0, begin0, end0;
It1 it1, begin1, end1;
public:
ChainedIter(It0 begin0, It0 end0, It1 begin1, It1 end1):
it0{begin0}, begin0{begin0}, end0{end0},
it1{begin1}, begin1{begin1}, end1{end1} {}
bool operator==(ChainedIter& rhs) const {
return it0 == rhs.it0 && it1 == rhs.it1;
}
bool operator!=(ChainedIter& rhs) const {
return !(*this == rhs);
}
ChainedIter* operator++() {
if(it0 != end0) ++it0;
else ++it1;
return this;
}
Pointee& operator*() {
if(it0 != end0) return *it0;
else return *it1; // UB if it1 == end1
}
ChainedIter end() {
auto newChainedIter = *this;
newChainedIter.it0 = newChainedIter.end0;
newChainedIter.it1 = newChainedIter.end1;
return newChainedIter;
}
ChainedIter begin() {
auto newChainedIter = *this;
newChainedIter.it0 = newChainedIter.begin0;
newChainedIter.it1 = newChainedIter.begin1;
return newChainedIter;
}
};
template<typename Cont1, typename Cont0>
decltype(auto) createIter(Cont0& cont0, Cont1& cont1) {
auto begin0 = cont0.begin();
auto end0 = cont0.end();
auto begin1 = cont1.begin();
auto end1 = cont1.end();
return ChainedIter<
typename Cont0::value_type,
typename Cont1::value_type,
typename Cont0::iterator,
typename Cont1::iterator> {begin0, end0, begin1, end1};
}
int main() {
std::vector<size_t> v(4, 20);
std::deque<size_t> d(3, 200);
auto iter = createIter(v, d);
std::for_each(iter.begin(), iter.end(), [](const auto& elt) {
std::cout << elt << ' ';
});
std::cout << std::endl;
}
I tried to make it work with different container types as long as they both are templated on the same object (which made sense as a kneejerk but maybe it can be enhanced to allow convertible types etc.). As seen in main() it works with vector as well as a deque.
My compiler version is:
$ g++ --version
g++ (GCC) 9.1.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
So maybe I could use template guides of C++17 to not depend on that additional function for type deduction convenience, but this itself took more than 10 mins for me to type and then some more to sort out compile bugs; plus I'm sure it's got loads of other horrible-for-production stuff anyway :P
An alternative to implement custom iterator (which is really verbose) is to provide a method to iterate over all elements:
struct PolyLine {
private:
vector<Point*> m_head_nodes;
vector<Point*> m_tail_nodes;
public:
template <typename F>
void VisitAllPoints(F&& f)
{
for (Point* p : m_head_nodes) {
f(p);
}
for (Point* p : m_tail_nodes) {
f(p);
}
}
};
And call it:
PolyLine pol = /*..*/;
pol.VisitAllPoints([](Point* p){ /*..*/});
Else, range-v3 library provides concatview (which is lazy):
struct PolyLine {
private:
vector<Point*> m_head_nodes;
vector<Point*> m_tail_nodes;
public:
auto allPoints() const { return ranges::view::concat(m_head_nodes, m_tail_nodes); }
auto allPoints() { return ranges::views::concat(m_head_nodes, m_tail_nodes); }
};
That you can use:
PolyLine pol = /*..*/;
for (Point* p : pol.allPoints()) {
/*..*/
}
EDIT: Thank you Jarod42 for skilfully fixing the bug in my previous code, as indeed the operator++ logic was flawed. I also changed the storage of the iterators to std::array to avoid unnecessary heap allocation.
This solution requires C++17, it uses a variant iterator type to accommodate for any kind of iterator, and it allows you to chain any number different collections.
#include <variant>
#include <array>
#include <vector>
#include <list>
#include <deque>
#include <iostream>
template<typename ContainerFirstT, typename ...ContainerRestT>
struct Chain
{
// Holds an iterator of any given container
typedef typename std::variant<typename ContainerFirstT::iterator,
typename ContainerRestT::iterator ...> IterT;
// Array of variant container iterators
typedef typename std::array<IterT, 1 + sizeof...(ContainerRestT)> IterArrayT;
// Iterator of array of variant iterators
typedef typename IterArrayT::const_iterator IterArrayIterT;
// Iterated type
typedef typename ContainerFirstT::value_type ValueT;
// Begin and end iterator of each container
IterArrayT begins;
IterArrayT ends;
struct ChainIter
{
// Begin and end of container being iterated
IterArrayIterT beginIt;
IterArrayIterT endIt;
IterArrayIterT endItSentinel;
// Iterator to current element of current container
IterT current;
ChainIter(IterArrayIterT beginIt, IterArrayIterT endIt, IterArrayIterT endItSentinel, IterT current)
: beginIt{beginIt}
, endIt{endIt}
, endItSentinel{endItSentinel}
, current{current}
{
}
bool operator==(ChainIter& it) const
{
return (beginIt == it.beginIt &&
endIt == it.endIt &&
current == it.current);
}
bool operator!=(ChainIter& it) const
{
return !(*this == it);
}
ChainIter& operator++()
{
// Go to next element
std::visit([](auto& it) { ++it; }, current);
// While there are elements to iterate in the current container
if (current == *endIt)
{
// When the container is finished move to the next one
++beginIt;
++endIt;
if (endIt != endItSentinel)
{
current = *beginIt;
}
}
return *this;
}
ValueT& operator*()
{
// Get value of current iterator
ValueT* value;
std::visit([&value](auto it) { value = &(*it); }, current);
return *value;
}
};
Chain(ContainerFirstT& containerFirst, ContainerRestT& ...containerRest)
: begins{containerFirst.begin(), containerRest.begin()...}
, ends{containerFirst.end(), containerRest.end()...}
{
}
ChainIter begin()
{
return ChainIter(begins.begin(), ends.begin(), ends.end(), begins.front());
}
ChainIter end()
{
return ChainIter(begins.end(), ends.end(), ends.end(), ends.back());
}
};
// Convenience factory
template<typename ...ContainersT>
Chain<ContainersT ...> make_chain(ContainersT& ...containers)
{
return Chain<ContainersT ...>(containers...);
}
// Example
int main()
{
std::vector<int> v = {1, 2, 3};
std::list<int> l = {4, 5};
std::deque<int> d = {6, 7, 8, 9};
auto chain = make_chain(v, l, d);
for (auto elem : chain)
{
std::cout << elem << std::endl;
}
return 0;
}
Output:
1
2
3
4
5
6
7
8
9
From this old question
C++ custom collection reverse_iterator with similar behaviour to std::vector implementation
I thought that the lines (after revising his design a bit)
template <typename Iterator>
class reverse_iterator {
Iterator _it;
public:
reverse_iterator(const Iterator& it):_it(it) { }
Iterator base() const {Iterator it = _it; return --it;}
typename Iterator::value_type& operator*() const {return *base();}
// ...
};
were correct (no one replied that they were incorrect). But it doesn't give the same output that this test with std::reverse_iterator gives:
#include <iostream>
#include <iterator>
#include <vector>
int main () {
std::vector<int> myvector = {1,2,3};
std::vector<int>::iterator it = std::next(myvector.begin());
std::reverse_iterator<std::vector<int>::iterator> r(it);
std::cout << *it << '\n'; // 2
std::cout << *r << '\n'; // 1
std::cout << *r.base() << '\n'; // 2
}
which seems to show that the lines should instead be
template <typename Iterator>
class reverse_iterator {
Iterator _it;
public:
reverse_iterator(const Iterator& it):_it(it) { }
Iterator base() const { return _it; }
typename Iterator::value_type& operator*() const { return *--base(); }
// ...
};
which would indeed give the same output as with std::reverse_iterator. What is correct here?
I have a class Foo that contains a map and provides begin() and end() functions to iterate over it:
class Foo {
typedef std::map<int, double> Container;
typedef Container::const_iterator const_iterator;
Container c_;
public:
const_iterator begin() const { return c_.begin(); }
const_iterator end() const { return c_.end(); }
void insert(int i, double d) { c_[i] = d; }
// ...
};
Now I would like to change it internally from std::map<int, double> to just a std::set<int>, but I don't want to break any client code.
So the double d in the insert function would now just be ignored. And the following code should still be valid, where it->second will now just always be 0.0:
Foo foo;
for(Foo::const_iterator it = foo.begin(); it != foo.end(); ++it) {
std::cout << it->first << " " << it->second << std::endl;
}
How can I make these changes in the Foo class?
In other words, how can I provide a Foo::const_iterator that adapts the new internal std::set<int>::const_iterator to behave like the old std::map<int,double>::const_iterator?
UPDATE: The reason I want to get rid of the map is memory efficiency. I have millions of Foo instances and cannot afford to store the double values in them.
Would using
std::set<std::pair<int, double> >
not be sufficient for this comparability?
Failing that you can always write your own iterator which wraps the std::list iterator and provides first and second members. Basically your operator++ would call operator++ on the real iterator etc. and the de-referencing operator could return either a temporary std::pair (by value) or a reference to a std::pair that lives within the iterator itself (if your legacy code can deal with that).
Update, slightly contrived example, might work depending on your scenario:
#include <iostream>
#include <set>
class Foo {
typedef std::set<int> Container;
typedef Container::const_iterator legacy_iterator;
Container c_;
// legacy iterator doesn't have a virtual destructor (probably?), shouldn't
// be a problem for sane usage though
class compat_iterator : public legacy_iterator {
public:
compat_iterator(const legacy_iterator& it) : legacy_iterator(it) {
}
const std::pair<int,double> *operator->() const {
static std::pair<int,double> value;
value = std::make_pair(**this, 0.0);
// Not meeting the usual semantics!
return &value;
}
};
public:
typedef compat_iterator const_iterator;
const_iterator begin() const { return c_.begin(); }
const_iterator end() const { return c_.end(); }
};
int main() {
Foo foo;
for(Foo::const_iterator it = foo.begin(); it != foo.end(); ++it) {
std::cout << it->first << " " << it->second << std::endl;
}
}
How about something like this?
#include <iostream>
#include <map>
#include <set>
struct Funky
{
int first;
static const double second;
Funky(int i)
: first(i)
{}
};
const double Funky::second = 0.0;
bool operator<(const Funky& lhs, const Funky& rhs)
{
return lhs.first < rhs.first;
}
class Foo
{
private:
//std::map<int,double> m_data;
std::set<Funky> m_data;
public:
//typedef std::map<int,double>::const_iterator const_iterator;
typedef std::set<Funky>::const_iterator const_iterator;
const_iterator begin() const
{
return m_data.begin();
}
const_iterator end() const
{
return m_data.end();
}
void insert(int i, double d)
{
//m_data.insert(std::make_pair(i, d));
m_data.insert(i);
}
};
int main()
{
Foo foo;
foo.insert(23, 9.0);
for(Foo::const_iterator it=foo.begin(), iend=foo.end(); it!=iend; ++it)
{
std::cout << it->first << ' ' << it->second << '\n';
}
return 0;
}
Perhaps something along the lines of
operator int()(const std::pair<int, double>& p) const {
return p.first;
}
maybe within some wrapper?
Perhaps you can define a fake_pair class that implements first and second and put a set<fake_pair> inside Foo.
You can't, not completely. The problem is you are changing your interface, which will always break your clients. I would recommend you create two new functions of newBegin and newEnd (or similar) which has your new behaviour. Your old interface you keep this the same but mark it as depreciated. The implementation of this old interface can use one of the work around described by the others.
I have a map where I'd like to perform a call on every data type object member function. I yet know how to do this on any sequence but, is it possible to do it on an associative container?
The closest answer I could find was this: Boost.Bind to access std::map elements in std::for_each. But I cannot use boost in my project so, is there an STL alternative that I'm missing to boost::bind?
If not possible, I thought on creating a temporary sequence for pointers to the data objects and then, call for_each on it, something like this:
class MyClass
{
public:
void Method() const;
}
std::map<int, MyClass> Map;
//...
std::vector<MyClass*> Vector;
std::transform(Map.begin(), Map.end(), std::back_inserter(Vector), std::mem_fun_ref(&std::map<int, MyClass>::value_type::second));
std::for_each(Vector.begin(), Vector.end(), std::mem_fun(&MyClass::Method));
It looks too obfuscated and I don't really like it. Any suggestions?
C++11 allows you to do:
for (const auto& kv : myMap) {
std::cout << kv.first << " has value " << kv.second << std::endl;
}
C++17 allows you to do:
for (const auto& [key, value] : myMap) {
std::cout << key << " has value " << value << std::endl;
}
using structured binding.
UPDATE:
const auto is safer if you don't want to modify the map.
You can iterate through a std::map object. Each iterator will point to a std::pair<const T,S> where T and S are the same types you specified on your map.
Here this would be:
for (std::map<int, MyClass>::iterator it = Map.begin(); it != Map.end(); ++it)
{
it->second.Method();
}
If you still want to use std::for_each, pass a function that takes a std::pair<const int, MyClass>& as an argument instead.
Example:
void CallMyMethod(std::pair<const int, MyClass>& pair) // could be a class static method as well
{
pair.second.Method();
}
And pass it to std::for_each:
std::for_each(Map.begin(), Map.end(), CallMyMethod);
C++14 brings generic lambdas.
Meaning we can use std::for_each very easily:
std::map<int, int> myMap{{1, 2}, {3, 4}, {5, 6}, {7, 8}};
std::for_each(myMap.begin(), myMap.end(), [](const auto &myMapPair) {
std::cout << "first " << myMapPair.first << " second "
<< myMapPair.second << std::endl;
});
I think std::for_each is sometimes better suited than a simple range based for loop. For example when you only want to loop through a subset of a map.
How about a plain C++? (example fixed according to the note by #Noah Roberts)
for(std::map<int, MyClass>::iterator itr = Map.begin(), itr_end = Map.end(); itr != itr_end; ++itr) {
itr->second.Method();
}
It's unfortunate that you don't have Boost however if your STL implementation has the extensions then you can compose mem_fun_ref and select2nd to create a single functor suitable for use with for_each. The code would look something like this:
#include <algorithm>
#include <map>
#include <ext/functional> // GNU-specific extension for functor classes missing from standard STL
using namespace __gnu_cxx; // for compose1 and select2nd
class MyClass
{
public:
void Method() const;
};
std::map<int, MyClass> Map;
int main(void)
{
std::for_each(Map.begin(), Map.end(), compose1(std::mem_fun_ref(&MyClass::Method), select2nd<std::map<int, MyClass>::value_type>()));
}
Note that if you don't have access to compose1 (or the unary_compose template) and select2nd, they are fairly easy to write.
For fellow programmers who stumble upon this question from google, there is a good way using boost.
Explained here : Is it possible to use boost::foreach with std::map?
Real example for your convenience :
// typedef in include, given here for info :
typedef std::map<std::string, std::string> Wt::WEnvironment::CookieMap
Wt::WEnvironment::CookieMap cookie_map = environment.cookies();
BOOST_FOREACH( const Wt::WEnvironment::CookieMap::value_type &cookie, cookie_map )
{
std::cout << "cookie : " << cookie.first << " = " << cookie.second << endl;
}
enjoy.
Will it work for you ?
class MyClass;
typedef std::pair<int,MyClass> MyPair;
class MyClass
{
private:
void foo() const{};
public:
static void Method(MyPair const& p)
{
//......
p.second.foo();
};
};
// ...
std::map<int, MyClass> Map;
//.....
std::for_each(Map.begin(), Map.end(), (&MyClass::Method));
Just an example:
template <class key, class value>
class insertIntoVec
{
public:
insertIntoVec(std::vector<value>& vec_in):m_vec(vec_in)
{}
void operator () (const std::pair<key, value>& rhs)
{
m_vec.push_back(rhs.second);
}
private:
std::vector<value>& m_vec;
};
int main()
{
std::map<int, std::string> aMap;
aMap[1] = "test1";
aMap[2] = "test2";
aMap[3] = "test3";
aMap[4] = "test4";
std::vector<std::string> aVec;
aVec.reserve(aMap.size());
std::for_each(aMap.begin(), aMap.end(),
insertIntoVec<int, std::string>(aVec)
);
}
From what I remembered, C++ map can return you an iterator of keys using map.begin(), you can use that iterator to loop over all the keys until it reach map.end(), and get the corresponding value:
C++ map
I wrote this awhile back to do just what you're looking for.
namespace STLHelpers
{
//
// iterator helper type for iterating through the *values* of key/value collections
//
/////////////////////////////////////////////
template<typename _traits>
struct _value_iterator
{
explicit _value_iterator(typename _traits::iterator_type _it)
: it(_it)
{
}
_value_iterator(const _value_iterator &_other)
: it(_other.it)
{
}
friend bool operator==(const _value_iterator &lhs, const _value_iterator &rhs)
{
return lhs.it == rhs.it;
}
friend bool operator!=(const _value_iterator &lhs, const _value_iterator &rhs)
{
return !(lhs == rhs);
}
_value_iterator &operator++()
{
++it;
return *this;
}
_value_iterator operator++(int)
{
_value_iterator t(*this);
++*this;
return t;
}
typename _traits::value_type &operator->()
{
return **this;
}
typename _traits::value_type &operator*()
{
return it->second;
}
typename _traits::iterator_type it;
};
template<typename _tyMap>
struct _map_iterator_traits
{
typedef typename _tyMap::iterator iterator_type;
typedef typename _tyMap::mapped_type value_type;
};
template<typename _tyMap>
struct _const_map_iterator_traits
{
typedef typename _tyMap::const_iterator iterator_type;
typedef const typename _tyMap::mapped_type value_type;
};
}
Here is an example of how you can use for_each for a map.
std::map<int, int> map;
map.insert(std::pair<int, int>(1, 2));
map.insert(std::pair<int, int>(2, 4));
map.insert(std::pair<int, int>(3, 6));
auto f = [](std::pair<int,int> it) {std::cout << it.first + it.second << std::endl; };
std::for_each(map.begin(), map.end(), f);