2012-05-09 9 views
5

Предположим, что существует вектор объектов класса.Вызов функции-члена каждого элемента вектора C++

vector<Object1> vec; 

Скажем, Object1 имеет функцию-член void foo(Object2*).

Я хочу сделать следующее:

for(int i=0; i<vec.size(); i++) { 
    vec[i].foo(obj2); 
} 

Как это может быть сделано без использования явного цикла?

+3

В чем проблема с использованием петли? – giorashc

+2

@giorashc, всегда предпочитайте алгоритм над циклом. Хотя на данный момент существует система ранжирования. – chris

+1

@giorashc Ничего страшного. Точно так же как 'for_each' применять функцию на элементах вектора, я хотел знать, есть ли способ вызвать функцию-член для каждого элемента вектора. – vikaspraj

ответ

6

Самый простой с TR1/C++ 11:

#include <vector> 
#include <functional> 
#include <algorithm> 

struct Object2{}; 

struct Object1 { 
    void foo(Object2*) {} 
}; 

int main() { 
    std::vector<Object1> vec; 
    Object2 obj2; 
    std::for_each(vec.begin(), vec.end(), std::bind(&Object1::foo, std::placeholders::_1, &obj2)); 
} 

Но вы также можете использовать std::for_each с std::bind2nd и std::mem_fun_ref, если это не вариант:

std::for_each(vec.begin(), vec.end(), std::bind2nd(std::mem_fun_ref(&Object1::foo), &obj2)); 
+0

Не делает for_each как цикл? –

+2

Это не ** явный ** цикл :) –

+1

@LuchianGrigore, это алгоритм, который должен быть предпочтительнее простого цикла. – chris

0

Один старый стиль должен вручную напишите функтор. Для более сложной логики это позволяет посвятить целый класс этой проблеме.

class fancyFunctor 
{ 
    Object2* m_data; 

public: 
    fancyFunctor(Object2 * data) : m_data(data){} 

    operator()(Object1 & ref) 
    { 
    ref.foo(m_data) 
    } 
} 

Тогда iteratate:

std::for_each(vec.begin(),vec.end(), fancyFunctor(&randomObject2)); 
-1

Readibility такого кода не является совершенным, и это не может быть сделано в любой простой однострочный способ. Это потому, что первый аргумент метода-члена некоторого класса является указателем на объект этого класса, на котором он будет выполнен.

В качестве альтернативы вы можете использовать цикл foreach, который поставляется с новым стандартом C++ 11 (но это все еще цикл).

+0

Вы заметите, что мой ответ имеет простой однострочный путь для C++ 11 и C++ 98/03, несмотря на указатель. – Flexo

+0

Да, вы правы - мое плохое. Не принимал во внимание связывание C++ 11/tr1 (сначала я должен был прочитать весь ваш пост). – gal

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