Вызовите функцию-член для каждого элемента в контейнере - PullRequest
8 голосов
/ 05 апреля 2009

Этот вопрос - вопрос стиля, так как вы всегда можете написать цикл for или что-то подобное; однако есть ли менее навязчивый STL или BOOST, эквивалентный написанию:

for (container<type>::iterator iter = cointainer.begin();
     iter != cointainer.end();
     iter++)
 iter->func();

Нечто подобное (воображаемое) это:

call_for_each(container.begin(), container.end(), &Type::func);

Я думаю, что это будет: 1) меньше печатать, 2) легче читать, 3) меньше изменений, если вы решите изменить базовый тип / тип контейнера.

EDIT: Спасибо за вашу помощь, что если я захочу передать некоторые аргументы функции-члену?

Ответы [ 4 ]

23 голосов
/ 05 апреля 2009
 #include <algorithm>  // for_each
 #include <functional> // bind

 // ...

 std::for_each(container.begin(), container.end(), 
                   std::bind(&Type::func));

Подробнее см. std::for_each и std::bind документацию.

Пропустил ваше редактирование: В любом случае, вот еще один способ достичь того, чего вы хотите, без использования Boost, если когда-либо понадобится:

std::for_each(foo_vector.begin(), foo_vector.end(),
    std::bind(&Foo::func, std::placeholders::_1));
5 голосов
/ 05 апреля 2009

Вы можете использовать std :: for_each или конструкции foreach boost .

Используйте BOOST_FOREACH или BOOST_REVERSE_FOREACH для boost, если вы не хотите перемещать логику в другую функцию.

4 голосов
/ 05 апреля 2009

Я обнаружил, что boost bind, кажется, хорошо подходит для этой задачи, плюс вы можете передать дополнительные аргументы методу:

#include <iostream>
#include <functional>
#include <boost/bind.hpp>
#include <vector>
#include <algorithm>

struct Foo {
    Foo(int value) : value_(value) {
    }

    void func(int value) {
        std::cout << "member = " << value_ << " argument = " << value << std::endl;
    }

private:
    int value_;
};

int main() {
    std::vector<Foo> foo_vector;

    for (int i = 0; i < 5; i++)
        foo_vector.push_back(Foo(i));

    std::for_each(foo_vector.begin(), foo_vector.end(),
        boost::bind(&Foo::func, _1, 1));
}
0 голосов
/ 05 апреля 2009

Если вы действительно хотите повысить производительность, а не просто улучшить свой код, то вам действительно нужна функция карты. Эрик Синк написал .net реализацию

...