2009-02-26 40 views
22

Một lần nữa tôi với vectơ. Tôi hy vọng tôi không quá khó chịu. Tôi có một cấu trúc như thế này:Vectơ, cấu trúc và tiêu chuẩn :: tìm

struct monster 
{ 
    DWORD id; 
    int x; 
    int y; 
    int distance; 
    int HP; 
}; 

Vì vậy, tôi đã tạo ra một vector:

std::vector<monster> monsters; 

Nhưng bây giờ tôi không biết làm thế nào để tìm kiếm thông qua các vector. Tôi muốn tìm một ID của quái vật bên trong vectơ.

DWORD monster = 0xFFFAAA; 
it = std::find(bot.monsters.begin(), bot.monsters.end(), currentMonster); 

Nhưng rõ ràng là nó không hoạt động. Tôi muốn lặp lại chỉ thông qua phần tử .id của cấu trúc, và tôi không biết làm thế nào để làm điều đó. Trợ giúp được đánh giá cao. Cảm ơn !

Trả lời

33

std::find_if:

it = std::find_if(bot.monsters.begin(), bot.monsters.end(), 
     boost::bind(&monster::id, _1) == currentMonster); 

Hoặc viết đối tượng chức năng của riêng bạn nếu bạn không có tăng. Sẽ trông như thế này

struct find_id : std::unary_function<monster, bool> { 
    DWORD id; 
    find_id(DWORD id):id(id) { } 
    bool operator()(monster const& m) const { 
     return m.id == id; 
    } 
}; 

it = std::find_if(bot.monsters.begin(), bot.monsters.end(), 
     find_id(currentMonster)); 
+0

sử dụng tăng cường, hoàn hảo! –

+0

Tôi tự hỏi, nếu tôi có '{int, int}', tôi có thể chuyển nó thành 'long' và sử dụng tìm kiếm bình thường không? –

+1

Ý nghĩa của "bot" trong bot.monsters.begin() là gì? –

13

Bạn cần phải viết ngữ tìm kiếm của riêng bạn:

struct find_monster 
{ 
    DWORD id; 
    find_monster(DWORD id) : id(id) {} 
    bool operator() (const monster& m) const 
    { 
     return m.id == id; 
    } 
}; 

it = std::find_if(monsters.begin(), monsters.end(), find_monster(monsterID)); 
+0

Câu trả lời hay, nhưng có lỗi đánh máy trong hàm tạo. Nó phải là ':' không ';' –

+0

Ngoài việc viết vị từ tìm kiếm của riêng bạn, bạn cần sử dụng 'std :: find_if' thay vì' std :: find'. –

7

Hãy nhìn vào các std::find mẫu, tham số thứ ba đặc biệt:

template<class InputIterator, class EqualityComparable> 
InputIterator find(InputIterator first, InputIterator last, 
       const EqualityComparable& value); 

EqualityComparable này là gì? Một lần nữa từ tài liệu:

A type is EqualityComparable if objects of that type can be 
compared for equality using operator==, and if operator== is 
an equivalence relation. 

Bây giờ, loại quái vật của bạn cần định nghĩa toán tử như vậy. Nếu bạn không trình biên dịch tạo ra một cho bạn (cũng như ctor mặc định và dtor) mà không một loại memcmp điều mà không hoạt động trong trường hợp của bạn. Vì vậy, để sử dụng std::find đầu tiên xác định một hàm so sánh/functor rằng các thuật toán có thể sử dụng để phù hợp với currentMonster tức là bạn cái gì đó dọc theo dòng:

struct monster { 
    // members 
    bool operator==(const monster& l, const monster& r) const 
    { 
    return l.id == r.id; 
    } 
}; 
+4

Tính năng này có hoạt động không? Tôi không có thành công vì định nghĩa toán tử bên trong một cấu trúc chỉ có thể có 1 đầu vào –

+0

Vấn đề tương tự như Snoozer. -1, vui lòng hoàn thành câu trả lời. –

7

thế nào về:

std::find_if(monsters.begin(), 
      monsters.end(), 
      [&cm = currentMonster] 
      (const monster& m) -> bool { return cm == m; }); 
+0

Ai đó có thể thấy điều này hướng dẫn tôi qua những gì nó đang làm?Cụ thể là [& cm = currentMonster] (const monster & m) -> bool {return cm == m; }); – 2kreate

+2

Ví dụ này sử dụng hàm lambda, phụ thuộc vào C++ 11. '[& cm = currentMonster]' liên kết biến 'currentMonster' từ phạm vi gọi đến tham chiếu cục bộ trong lambda, được gọi là' cm'. Sau đó '(const monster & m) -> bool' định nghĩa chữ ký của lambda, lấy một tham số đầu vào,' m' và trả về 'bool'. Phần thân của hàm lambda là '{return cm == m; } ', trả về true nếu' cm' và 'm' so sánh bằng nhau. –

+0

Cuối cùng tôi biết cách ràng buộc đúng các biến cục bộ với lambdas. –

1

hoặc đặt những con quái vật trong bản đồ thay vì một vector

hoặc nếu họ phải ở trong một vector tạo ra một bản đồ bản đồ chỉ số tức là ID để chỉ số véc tơ

0

Đây là một comple te mẫu dựa trên câu trả lời của Johannes Schaub (phiên bản nâng cao).

#include <algorithm> 
#include <boost/bind.hpp> 

struct monster 
{ 
    DWORD id; 
    int x; 
    int y; 
    int distance; 
    int HP; 
}; 

int main() 
{ 
    std::vector<monster> monsters; 

    monster newMonster; 
    newMonster.id = 1; 
    newMonster.x  = 10; 
    monsters.push_back (newMonster); 

    newMonster.id = 2; 
    newMonster.x  = 20; 
    monsters.push_back (newMonster); 

    newMonster.id = 2; 
    newMonster.x  = 30; 
    monsters.push_back (newMonster); 

    DWORD monsterId = 2; 

    std::vector<monster>::iterator it = std::find_if (monsters.begin(), monsters.end(), 
     boost::bind (&monster::id, _1) == monsterId); 

    return 0; 
} 
Các vấn đề liên quan