#include <string>
#include <iostream>
#include <boost/foreach.hpp>
#include <iterator>

template<typename A, typename B>
struct zip_iterator{
  typedef typename A::iterator left;
  typedef typename B::iterator right;
  typedef std::pair<left, right> value_type;
  typedef std::forward_iterator_tag iterator_category;
  typedef void difference_type;
  typedef value_type* pointer;
  typedef value_type& reference;

  value_type it;

  zip_iterator(){}
  zip_iterator(left ai, right bi) : it(ai, bi) {}

  bool operator == (zip_iterator i) { return it.first == i.it.first && it.second == i.it.second; }
  bool operator != (zip_iterator i) { return !(*this == i); }

  zip_iterator& operator ++ () { it.first++; it.second++; return *this; }
  zip_iterator operator ++ (int) { zip_iterator t = *this; ++(*this); return t; }

  value_type& operator * () { return it; }
  value_type* operator -> () { return &it; }
};


template<typename A, typename B>
struct zip {
  A& a;
  B& b;

  zip(A& a, B& b) : a(a), b(b) {}

  typedef typename A::iterator left;
  typedef typename B::iterator right;
  typedef std::pair<left, right> value_type;
  typedef zip_iterator<A, B> iterator;
  typedef zip_iterator<A, B> const_iterator;

  iterator begin() const { return iterator(a.begin(), b.begin()); }
  iterator end() const { return iterator(a.end(), b.end()); }
};

typedef zip<std::string, std::string> string_zip;

int main()
{
    std::string hello( "Hello" );
    std::string world( "world" );
    
    string_zip zz(hello, world);

    BOOST_FOREACH( string_zip::value_type val , zz )
    {
        std::cout << *val.first << *val.second;
    }

    return 0;
}