
Iterating over the first and second elements of a collection of pairs is a pretty common problem. Would it be possible to get something like the following into boost? #include <boost/iterator/iterator_adaptor.hpp> /* For testing, below */ #include <map> #include <string> #include <iostream> #include <iterator> template<typename BaseIt> struct first_iterator : boost::iterator_adaptor< first_iterator<BaseIt>, BaseIt, typename BaseIt::value_type::first_type > { first_iterator() : first_iterator::iterator_adaptor_() {} first_iterator(const BaseIt& bi) : first_iterator::iterator_adaptor_(bi) {} operator const BaseIt&() { return this->base_reference(); } private: friend struct boost::iterator_core_access; typename BaseIt::value_type::first_type& dereference() const { return this->base_reference()->first; } }; template<typename T> first_iterator<T> make_first_iterator(const T& it) { return first_iterator<T>(it); } template<typename BaseIt> struct second_iterator : boost::iterator_adaptor< second_iterator<BaseIt>, BaseIt, typename BaseIt::value_type::second_type > { second_iterator() : second_iterator::iterator_adaptor_() {} second_iterator(const BaseIt& bi) : second_iterator::iterator_adaptor_(bi) {} operator const BaseIt&() { return this->base_reference(); } private: friend struct boost::iterator_core_access; typename BaseIt::value_type::second_type& dereference() const { return this->base_reference()->second; } }; template<typename T> second_iterator<T> make_second_iterator(const T& it) { return second_iterator<T>(it); } int main() { typedef std::map<int, std::string> testmap; testmap t; t.insert(std::pair<int, std::string>(5, "middle")); t.insert(std::pair<int, std::string>(2, "first")); t.insert(std::pair<int, std::string>(8, "last")); std::copy(make_first_iterator(t.begin()), make_first_iterator(t.end()), std::ostream_iterator<int>(std::cout, " ")); std::cout << "\n"; std::copy(make_second_iterator(t.begin()), make_second_iterator(t.end()), std::ostream_iterator<std::string>(std::cout, " ")); std::cout << "\n"; first_iterator<testmap::iterator> x = t.begin(); ++x; t.erase(x); }