#include <utility>
#include <set>
#include <iostream>
#include <algorithm>

template<class T>
class CompareWords {
public:
    bool operator()(T s1, T s2)
    {
        if (s1.length() == s2.length())
        {
            return ( s1 < s2 );
        }
        else return ( s1.length() < s2.length() );
    }
};

    template<class Iterator, class Clumps, class Compare>
    void reduce_clumps( Iterator begin, Iterator end, Clumps&& clumps, Compare&& compare) {
      if (begin==end) return;
      typedef decltype(*begin) value_type;
      std::size_t count = 1;
      Iterator run_end = std::find_if( std::next(begin), end, [&]( value_type v ){
        if (!compare(*begin, v)) {
          ++count;
          return false;
        }
        return true;
      });
      clumps( begin, run_end, count );
      return reduce_clumps( std::move(run_end), std::move(end), std::forward<Clumps>(clumps), std::forward<Compare>(compare) );
    }

    int main() {
      typedef std::multiset<std::string> mySet;
      typedef std::multiset<std::string>::iterator mySetItr;

      mySet mWords { "A", "A", "B" };

      reduce_clumps( mWords.begin(), mWords.end(),
        []( mySetItr run_start, mySetItr run_end, std::size_t count )
        {
          std::cout << "Word \"" << *run_start << "\" occurs " << count << " times\n";
        },
        CompareWords<std::string>{}
      );
    }