If I have a container (vector
, list
, etc) where each element is a std::pair
, is there an easy way to iterate over each element of each pair?
i.e.
std::vector<std::pair<int,int> > a;
a.push_back(std::pair(1,3));
a.push_back(std::pair(2,3));
a.push_back(std::pair(4,2));
a.push_back(std::pair(5,2));
a.push_back(std::pair(1,5));
and then being able to iterate over the value: 1,3,2,3,4,2,5,2,1,5?
Similarly, what type of functor/function would return to me a container (of the same type) with a flat listing of the pair elements as above?
For your first, you have to create your own iterator class, which pairs a flag indicating the within-pair position with a container<pair>
iterator
For the second, it's easier, although to be as general as you want (container of same type) you need a template typedef. Here's for just vector:
template <class V>
std::vector<V> flatten_pairs(std::vector<std::pair<V,V> > const& a) {
typedef std::vector<std::pair<V,V> > A;
std::vector<V> ret;
for (typename A::const_iterator i=a.begin(),e=a.end();i!=e;++i) {
ret.push_back(i->first);
ret.push_back(i->second);
}
return ret;
}
Here's how you fake a template typedef:
template <class C>
struct same_container;
template <class V>
struct same_container<std::vector<V> > {
template <class W> struct rebind { typedef std::vector<W> type; };
};
template <class V>
struct same_list<std::list<V> > {
template <class W> struct rebind { typedef std::list<W> type; };
};
template <class C>
typename same_container<C>::rebind<typename C::value_type::first_type>::type
flatten_pairs(C const& a);
The following code will print all values as required:
for ( size_t x = 0; x < a.size(); ++x ) {
cout << a[x].first << "," << a[x].second << ",";
}
I'd prefer this easy way than creating custom iterator.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With