2010-05-01 5 views
3

J'ai un std::map, et je voudrais définir un itérateur qui renvoie des valeurs modifiées. En règle générale, un std::map<int,double>::iterator itère sur std::pair<int,double>, et je voudrais le même comportement, juste la double valeur est multipliée par une constante.Comment itérer sur des valeurs std :: map modifiées?

Je l'ai essayé avec boost::transform_iterator, mais il ne compile pas:

#include <map> 
#include <boost/iterator/transform_iterator.hpp> 
#include <boost/functional.hpp> 

typedef std::map<int,double> Map; 
Map m; 
m[100] = 2.24; 

typedef boost::binder2nd< std::multiplies<double> > Function; 
typedef boost::transform_iterator<Function, 
            Map::value_type*> MultiplyIter; 

MultiplyIter begin = 
    boost::make_transform_iterator(m.begin(), 
           Function(std::multiplies<double>(), 4)); 
// now want to similarly create an end iterator 
// and then iterate over the modified map 

L'erreur est:

error: conversion from 'boost 
::transform_iterator< 
    boost::binder2nd<multiplies<double> >, gen_map<int, double>::iterator 
    , boost::use_default, boost::use_default 
>' to non-scalar type 'boost::transform_iterator< 
    boost::binder2nd<multiplies<double> >, pair<const int, double> * 
    , boost::use_default, boost::use_default 
>' requested 

Qu'est-ce que gen_map et dois-je vraiment besoin?

J'adapté le code tutoriel transform_iterator de here écrire ce code ...

+0

Il est bien ce coup de pouce rend cela possible du tout, mais je souhaite qu'il y avait des solutions beaucoup plus simples disponibles ... – Frank

Répondre

5

std :: multiplie qui attend un double comme premier argument, et pas une paire std ::.

La fonction de transformation doit prendre un seul argument std :: pair (les éléments de la carte étant une paire de valeurs de clé) et renvoyer ce que vous voulez.

La fonction suivante peut être utilisée à la place de std :: multiply.

double times(std::pair<int,double> const& p, int i) { 
    return i*p.second; 
} 

boost::make_transform_iterator(m.begin(), 
           Function(times, 4)); 
+0

Est-ce que le 'typedef' pour les besoins de la fonction pour changer pour cela? – Frank

+0

Oui, il est nécessaire de le remplacer par value_type par un type d'itérateur répondant à Potatowatter. –

2
typedef boost::transform_iterator<Function, 
    Map::iterator> MultiplyIter; // value_type* only occasionally 
           // works as an iterator 

gen_map semble être le nom de la classe qui sous-tend std::map.

Le didacticiel utilise int* car le pointeur est le type approprié pour itérer sur un tableau de style C.

Questions connexes