2010-03-10 4 views
9

У меня есть вектор указателей. Я хотел бы вызвать функцию для каждого элемента, но эта функция принимает ссылку. Есть ли простой способ разыменовать элементы?Использование for_each и boost :: bind с вектором указателей

Пример:

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

я мог бы создать маленький грязный обертку, которая принимает указатель, но я полагал, что должно было быть лучше?

+0

Есть ли причина, по которой вы используете 'boost :: ref (* this)'? Я просто использую: boost :: bind (& MyClass :: ReferenceFn, this, _1), и он отлично работает. –

ответ

15

Вы можете использовать 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)); 

Это будет разыменования итератора адаптированной дважды в своей operator*.

+4

+1, хотя для этого случая я предпочитаю 'BOOST_FOREACH (Element * e, elements) this-> ReferenceFn (* e);'. C++ может использоваться как функциональный язык, но не как * сжатый * функциональный язык ... –

+0

И Python будет 'для e в элементах: self.ReferenceFn (e)'. Это потрясающе. –

+4

Для C++ 0x это будет 'for (auto * e: elements) ReferenceFn (* e);'. Sweet :) –

3

Похоже, вы также можете использовать библиотеку 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)); 

Но я согласен с комментаторами о предпочитая BOOST_FOREACH. Алгоритм «for_each» практически ничего не полезен, и то, что он делает, цикл, основанный на диапазоне, может сделать для вас гораздо меньшие усилия.

Смежные вопросы