std :: copie en std :: cout pour std :: paire
J'ai de code suivant:
#include <iostream>
#include <algorithm>
#include <map>
#include <iterator>
//namespace std
//{
std::ostream& operator << ( std::ostream& out,
const std::pair< size_t, size_t >& rhs )
{
out << rhs.first << ", " << rhs.second;
return out;
}
//}
int main()
{
std::map < size_t, size_t > some_map;
//fill some_map with random values
for ( size_t i = 0; i < 10; ++i )
{
some_map[ rand() % 10 ] = rand() % 100;
}
//now I want to output this map
std::copy(
some_map.begin(),
some_map.end(),
std::ostream_iterator<
std::pair< size_t, size_t > >( std::cout, "\n" ) );
return 0;
}
Dans ce code, je veux juste copier la carte de flux de sortie. Pour ce faire, j'ai besoin de définir l'opérateur <<(..) - OK.
Mais, d'après les noms de trouver des règles compilateur ne peut pas trouver mon opérateur<<().
Parce que std::cout, std::pair et std::copy qui a appelé mon opérateur<< - à partir de l'espace de noms std.
Solution rapide - ajouter mes oerator<< espace de noms std - mais c'est moche, à mon humble avis.
Quelles solutions ou une solution de contournement pour ce problème, savez-vous?
source d'informationauteur bayda
Vous devez vous connecter pour publier un commentaire.
Il n'existe pas de méthode standard pour le cout d'un
std::pair
parce que, eh bien, la façon dont vous souhaitez imprimer est probablement différente de la façon dont le gars à côté il veut. C'est un bon cas d'utilisation d'un foncteur ou une fonction lambda. Vous pouvez passer ensuite que comme un argument destd::for_each
pour faire le travail.À l'appel de ce foncteur à partir de votre code:
J'ai fondé une nouvelle manière élégante de résoudre ce problème.
J'ai beaucoup d'intérêt les idées lors de la lecture des réponses:
Je pense que je vais utiliser toutes ces idées dans l'avenir, pour résoudre différents problèmes.
Mais pour ce cas, j'ai understaded que je peux formuler ma bproblem "transformer la carte de données de chaînes de caractères et de les écrire dans flux de sortie" au lieu de "copier la carte, les données relatives au flux de sortie". Ma solution ressemble:
Je pense que cette méthode est plus court et plus expressive que les autres.
Je voudrais juste faire remarquer que l'ajout de choses pour le std:: espace de noms est illégale selon la Norme C++ (voir la section 17.4.3.1).
Ce que vous voulez, c'est une transformation d'itérateur. Ce type d'itérateur enveloppe un autre itérateur, en avant toutes les méthodes de positionnement comme opérateur++ et l'opérateur==, mais redéfinit l'opérateur* et opérateur->.
Croquis rapide :
Juste de passage, mais de ce fait le travail pour moi, de sorte qu'il peut pour quelqu'un d'autre (version réduite):
Cas d'utilisation donné:
Utilisation de Boost Lambda, vous pouvez essayer quelque chose comme cela. La version que j'ai de Boost Lambda, cela ne fonctionne pas, je vais le tester et corriger plus tard.
[Je préfère supprimer cette réponse, mais je vais le laisser pour l'instant, au cas où quelqu'un trouve la discussion intéressante.]
Puisque c'est une prolongation raisonnable du std bibliothèque, je venais de mettre dans l'espace de noms std, surtout si c'est une chose. Vous pouvez simplement déclarer statique pour l'empêcher de causer des erreurs d'édition de liens, si quelqu'un d'autre faire la même chose à un autre endroit.Une autre solution qui vient à l'esprit est de créer un wrapper pour le std::pair:
plus simple et universelle !
--- Il est très bien avec C++11