2012-05-09 32 views
5

Giả sử có một vectơ của các đối tượng lớp.Gọi hàm thành viên của mọi phần tử của vector C++

vector<Object1> vec; 

Giả sử, Object1 có chức năng thành viên void foo(Object2*).

Tôi muốn làm như sau:

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

Làm thế nào điều này có thể được thực hiện mà không sử dụng một vòng lặp rõ ràng?

+3

có gì sai khi sử dụng vòng lặp? – giorashc

+2

@giorashc, luôn thích một thuật toán hơn một vòng lặp. Mặc dù, hiện nay đã có nhiều thay đổi. – chris

+1

@giorashc Không có gì sai. Cũng giống như có 'for_each' để áp dụng hàm trên các phần tử của một vectơ, tôi muốn biết nếu có một số cách gọi hàm thành viên cho mọi phần tử của một vectơ. – vikaspraj

Trả lời

6

dễ nhất với 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)); 
} 

Nhưng bạn cũng có thể sử dụng std::for_each với std::bind2nd, và std::mem_fun_ref nếu đó không phải là một lựa chọn:

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

Không for_each được tính là vòng lặp? –

+2

Nó không phải là một vòng lặp ** ** rõ ràng :) –

+1

@LuchianGrigore, đó là một thuật toán, mà nên được ưa thích trên một vòng lặp đơn giản. – chris

0

Một già phong cách tự viết một functor. Đối với logic phức tạp hơn, điều này cho phép bạn dành toàn bộ một lớp cho vấn đề.

class fancyFunctor 
{ 
    Object2* m_data; 

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

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

Sau đó, để iteratate:

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

readibility mã như vậy là không hoàn hảo, và nó không thể được thực hiện trong bất kỳ cách nào một dòng đơn giản. Đó là vì, đối số đầu tiên của phương thức thành viên của một số lớp là con trỏ tới đối tượng của lớp này, trên đó nó sẽ được thực hiện.

Hoặc bạn có thể sử dụng vòng lặp foreach đi kèm với tiêu chuẩn C++ 11 mới (nhưng nó vẫn là vòng lặp).

+0

Bạn sẽ nhận thấy câu trả lời của tôi có một cách một dòng đơn giản cho cả C++ 11 và C++ 98/03, mặc dù con trỏ. – Flexo

+0

Có, bạn đúng - xấu của tôi. Đã không đi vào xem xét C + + 11/tr1 ràng buộc (lúc đầu, tôi nên đã đọc toàn bộ bài viết của bạn). – gal

Các vấn đề liên quan