2009-01-27 6 views
7

Je sais que cette question a déjà été soulevée sous différentes formes, mais c'est légèrement différent.Touches/Valeurs Fonctionnalité pour les itérateurs en C++

J'ai une classe qui contient une carte std :: map. Bien que je souhaite utiliser la carte à d'autres fins à l'intérieur de la classe, je souhaite exposer extérieurement un adaptateur d'itérateur aux seules valeurs de la carte (ie le deuxième élément de la paire std ::).

Par exemple en python que je pourrais faire quelque chose comme ceci:

def __iter__(self): 
    return self._dict.itervalues() 

Comment puis-je le faire cela en C++, en se cachant la mise en œuvre dans la classe?

Merci,

Dan

Répondre

16

Jetez un oeil à Boost de transform_iterator qui fournit exactement ce type de fonctionnalité:

template <typename K, typename V> 
struct get_value { 
    const V& operator()(std::pair<K, V> const& p) { return p.second; } 
}; 

class your_class { 
    typedef map<int, float> TMap; 
    TMap mymap; 

public: 
    typedef get_value<TMap::key_type, TMap::data_type> F; 
    typedef 
     boost::transform_iterator<F, TMap::iterator> 
     value_iterator; 

    value_iterator begin() { return make_transform_iterator(mymap.begin(), F()); } 

    value_iterator end() { return make_transform_iterator(mymap.end(), F()); } 

    // TODO Same for const versions. 
    // Rest of the interface … 
}; 

Maintenant, vous pouvez itérer sur les valeurs, par exemple comme ceci:

your_class c; 
// Fill c with some values … 
copy(c.begin(), c.end(), ostream_iterator<float>(cout, " ")); 
+0

hmm, je ne peux pas obtenir ceci à compiler, devrait-il vraiment y avoir aucun type de retour sur l'opérateur get_value()? – Dan

+0

Vous avez raison, c'est modifié. –

+0

Stack Overflow est tellement cool. (Je n'ai pas pu tester le code, je n'ai pas installé Boost à la maison.) –

Questions connexes