2010-03-10 8 views
9

J'ai un vecteur de pointeurs. Je voudrais appeler une fonction pour chaque élément, mais cette fonction prend une référence. Existe-t-il un moyen simple de déréférencer les éléments?Utiliser for_each et boost :: bind avec un vecteur de pointeurs

Exemple:

MyClass::ReferenceFn(Element & e) { ... } 

MyClass::PointerFn(Element * e) { ... } 

MyClass::Function() 
{ 
    std::vector< Element * > elements; 
    // add some elements... 

    // This works, as the argument is a pointer type 
    std::for_each(elements.begin(), elements.end(), 
        boost::bind(&MyClass::PointerFn, boost::ref(*this), _1)); 

    // This fails (compiler error), as the argument is a reference type 
    std::for_each(elements.begin(), elements.end(), 
        boost::bind(&MyClass::ReferenceFn, boost::ref(*this), _1)); 
} 

je pouvais créer un petit emballage sale qui prend un pointeur, mais je me suis dit qu'il devait y avoir une meilleure façon?

+0

Y a-t-il une raison pour laquelle vous utilisez 'boost :: ref (* this)'? Je viens d'utiliser: boost :: bind (& MyClass :: ReferenceFn, this, _1) et ça marche bien. –

Répondre

15

Vous pouvez utiliser boost::indirect_iterator:

std::for_each(boost::make_indirect_iterator(elements.begin()), 
       boost::make_indirect_iterator(elements.end()), 
       boost::bind(&MyClass::ReferenceFn, boost::ref(*this), _1)); 

qui déréférencer l'itérateur adapté deux fois dans son operator*.

+4

+1, bien que pour ce cas je préfère 'BOOST_FOREACH (Element * e, éléments) this-> ReferenceFn (* e);'. C++ peut être utilisable comme un langage fonctionnel, mais pas comme un langage fonctionnel * concis ... –

+0

Et le Python serait 'pour e dans les éléments: self.ReferenceFn (e)'. C'est déchirant. –

+4

Pour C++ 0x ce sera 'pour (auto * e: elements) ReferenceFn (* e);'. Sweet :) –

3

Il semble que vous pouvez également utiliser la bibliothèque Boost.Lambda.

// Appears to compile with boost::lambda::bind 
    using namespace boost::lambda; 
    std::for_each(elements.begin(), elements.end(), 
        bind(&MyClass::ReferenceFn, boost::ref(*this), *_1)); 

Mais je suis d'accord avec les commentateurs au sujet préférant BOOST_FOREACH. Le "algorithme" for_each ne fait pratiquement rien d'utile, et ce qu'il fait, basé sur la gamme pour la boucle peut faire pour vous avec un effort beaucoup plus petit.