
Like the following: I guess it depends on how much you're willing to pay for syntactic sugar... //----------------------------------------------------------------------------- #include <iostream> #include <vector> #include <deque> #include <list> #include <utility> #include "each.hpp" template<typename T1, typename T2> std::ostream& operator<< (std::ostream& os, const std::pair<T1, T2>& p) { return os << "{" << p.first << "," << p.second << "}"; } int main(int, char**) { std::vector<int> int_vector; int_vector.push_back(5); int_vector.push_back(10); for (each<int> in(int_vector); in; ++in) std::cout << *in << std::endl; std::deque<double> double_deque; double_deque.push_back(3.14); double_deque.push_front(99.999); for (each<double> in(double_deque); in; ++in) std::cout << *in << std::endl; std::list<std::pair<unsigned, char> > pair_list; pair_list.push_back(std::make_pair(10, 'a'+13)); pair_list.push_back(std::make_pair(11, 'a'+14)); for (each<std::pair<unsigned, char> > in(pair_list); in; ++in) std::cout << *in << std::endl; std::list<int> int_list(3); for (each<int> in(int_list); in; ++in) *in = 5; for (each<const int> in(int_list); in; ++in) std::cout << *in << std::endl; return 0; } //-- each.hpp ----------------------------------------------------------------- #include <boost/function.hpp> #include <boost/bind.hpp> template<typename T> struct each { typedef T value_type; template<typename ContainerType> each(ContainerType& c) : iter(c.begin(), c.end()) {} operator bool(void) const { return iter.at_end() == false; } void operator++(void) { iter.increment(); } value_type& operator*(void) const { return iter.dereference(); } private: struct iterator_wrapper { struct iterator_storage { // Allocate a memory buffer sized to hold a real iterator, and copy it template<typename BaseIteratorType> iterator_storage(const BaseIteratorType& t) : address(operator new(sizeof t)) { BaseIteratorType* typed_address = reinterpret_cast<BaseIteratorType*>(address); *typed_address = t; } ~iterator_storage() { operator delete(address); } void* address; }; template<typename IteratorType> iterator_wrapper(IteratorType begin, IteratorType end) : current_storage(begin), end_storage(end) { // Make bound references to the operations we need, on the iterator copy IteratorType* saved_begin = reinterpret_cast<IteratorType*>(current_storage.address); increment = boost::bind(&IteratorType::operator++, saved_begin); dereference = boost::bind(&IteratorType::operator*, saved_begin); IteratorType* saved_end = reinterpret_cast<IteratorType*>(end_storage.address); at_end = boost::bind(&iterator_wrapper::is_equal<IteratorType>, saved_begin, saved_end); } template<typename IteratorType> static bool is_equal(const IteratorType* first, const IteratorType* second) { return (*first == *second); } boost::function<void (void)> increment; boost::function<value_type& (void)> dereference; boost::function<bool (void)> at_end; iterator_storage current_storage; iterator_storage end_storage; }; iterator_wrapper iter; };