Para los datos de entrada sabemos que con utilizar un pair<string, string> es suficiente, por eso una solución era crear el StrPair, para el ostream_iterator esto cambia un poco, ya que los datos provienen de dos tipos diferentes de datos, esto es, un pair<string, string> y un pair<string, int> del multimap y map respectivamente, por esto último, lo que conviene ahora es reescribir la clase que hereda de pair de manera genérica y sobrecargando ambos operadores "extracción" e "inserción" para la misma.
Ejemplo:
Código C++:
Ver original#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
#include <map>
#include <string>
#include <iterator>
using namespace std;
class MiFuncion{
map<string, int>& d;
public:
MiFuncion(map<string, int>& rd):d(rd){}
void operator()(pair<string, string> t){
map<string, int>::iterator i;
i = d.find(t.first);
if (i != d.end()) // Existe clave
d[t.first] += 1;
else
d.insert(i, pair<string,int>(t.first,1));
}
};
template<class T1, class T2>
class MyPair : public pair<T1, T2>{
public:
MyPair():pair<T1, T2>(){}
MyPair(T1 t1, T2 t2):pair<T1, T2>(t1, t2){}
template <class U, class V>
MyPair(const pair<U,V> &rp):pair<T1, T2>(rp){ }
friend istream& operator>>(istream& is, MyPair& pa){
return is >> pa.first >> pa.second;
}
friend ostream& operator<<(ostream& os, const MyPair& pa){
return os << "[" << pa.first << ", " << pa.second << "]";
}
};
int main ()
{
multimap<string, string> multi;
map<string,int> d;
cout << "Vaya insertando las claves en la forma K1, K2" << endl;
cout << "Presione ctrl+z para finalizar" << endl;
copy(istream_iterator<MyPair<string, string> >(cin), istream_iterator<MyPair<string, string> >(), inserter(multi, multi.begin()));
cout << endl << "Elementos del multidiccionario: " << endl;
copy (multi.begin(), multi.end(), ostream_iterator<MyPair<string, string> >(cout, "\n"));
for_each (multi.begin(), multi.end(), MiFuncion(d));
cout << endl << "Elementos del diccionario: " << endl;
copy (d.begin(), d.end(), ostream_iterator<MyPair<string, int> >(cout, "\n"));
return 0;
}
Fíjate que en la clase MyPair el constructor copia es un template, es importante hacerlo de esta forma ya que en la clase pair así está definido, esto lo que te permite es crear un nuevo pair a partir de otro que tenga el mismo tipo de datos o diferente pero cuya conversión de los mismos resulte válida.
Saludos.