2010-03-10 9 views
9

Tengo un vector de punteros. Me gustaría llamar a una función para cada elemento, pero esa función toma una referencia. ¿Hay una forma simple de desreferenciar los elementos?Usando for_each y boost :: bind con un vector de punteros

Ejemplo:

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)); 
} 

que podría crear un pequeño envoltorio sucia que toma un puntero, pero pensé que tenía que haber una mejor manera?

+0

¿Hay algún motivo por el que esté utilizando 'boost :: ref (* this)'? Solo uso: boost :: bind (& MyClass :: ReferenceFn, this, _1) y funciona bien. –

Respuesta

15

Usted podría utilizar 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)); 

que la voluntad eliminar la referencia al iterador adaptada dos veces en su operator*.

+4

+1, aunque para este caso prefiero 'BOOST_FOREACH (Elemento * e, elementos) this-> ReferenceFn (* e);'. C++ puede usarse como un lenguaje funcional, pero no como un lenguaje * conciso * funcional ... –

+0

Y el Python sería 'para e en elementos: self.ReferenceFn (e)'. Es desgarrador –

+4

Para C++ 0x será 'for (auto * e: elements) ReferenceFn (* e);'. Dulce :) –

3

Parece que también podría utilizar la biblioteca 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)); 

pero estoy de acuerdo con los comentaristas sobre prefiriendo BOOST_FOREACH. El "algoritmo" for_each no hace prácticamente nada útil, y lo que hace, el bucle basado en rango puede hacer por usted con un esfuerzo mucho menor.

Cuestiones relacionadas