2009-02-26 6 views
22

다시 벡터와 함께. 나는 너무 성가 시게하지 않기를 바란다. 벡터, 구조체 및 표준 :: 찾기

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

그래서 내가 벡터 생성 :

std::vector<monster> monsters; 

을하지만 지금은 벡터를 검색하는 방법을 모르는 나는이 같은 구조체가 있습니다. 벡터 안에있는 몬스터의 ID를 찾고 싶습니다.

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

하지만 분명히 작동하지 않습니다. 구조체의 .id 요소를 통해서만 반복하고 싶고 그 방법을 모른다. 도움말 크게 감사드립니다. 감사 !

답변

33

std::find_if을 : 당신이 부스트가없는 경우

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

또는 자신의 함수 객체를 작성합니다.

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

이 EqualityComparable로 무엇입니까 :이

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

부스트를 사용하여 Perfect! –

+0

'{int, int}'가 있으면 'long'으로 캐스팅하고 정상적으로 사용할 수 있습니까? –

+1

bot.monsters.begin()의 "bot"의 의미는 무엇입니까? –

13

당신은 당신의 자신의 검색 조건을 작성해야합니다 :

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

멋진 답변이지만 생성자에 오타가 있습니다. ':'이 아닌 ';'이되어야합니다. –

+0

자신 만의 검색 술어를 작성하는 것 외에도'std :: find' 대신'std :: find_if'를 사용해야합니다. –

7

과 같을 것이다 것은 std::find 템플릿을 살펴, 특히 세 번째 매개 변수를 타고? 다시 설명서에서 :

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

이제 괴물이 이러한 연산자를 정의해야합니다. 당신이하지 않으면 컴파일러는 memcmp 일을 당신의 경우에는 작동하지 않는 (당신도 기본 ctor와 dtor 같이) 하나를 생성합니다.

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

이 방법이 효과가 있습니까? 구조체 내부의 연산자 정의는 1 개의 입력 만 가질 수 있기 때문에 성공하지 못했습니다. –

+0

Snoozer와 같은 문제입니다. -1, 대답을 완료하십시오. –

7

방법에 대한 : 그래서, 알고리즘의 라인을 따라 당신의 currentMonster 즉 무언가에 맞게 사용할 수있는 최초의 비교기 기능/펑터를 정의 std::find를 사용하는

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

이 일을 보는 누군가가 나를 통해 걸을 수 있을까요?구체적으로 [& cm = currentMonster] (const 몬스터 & m) -> bool {return cm == m; }); – 2kreate

+2

이 예제는 C++ 11에 의존하는 람다 함수를 사용합니다. '[& cm = currentMonster]'는 호출 범위의 변수'currentMonster'를'cm'이라는 람다의 로컬 참조에 바인드합니다. 그런 다음'(const monster & m) -> bool'은 람다의 서명을 정의하고 하나의 입력 매개 변수'm'을 가져 와서'bool'을 반환합니다. 람다 함수의 몸체는'{return cm == m; 'cm'와'm'이 동등하다고 비교하면 true를 반환합니다. –

+0

마지막으로 로컬 변수를 lambdas에 제대로 바인딩하는 방법을 알고 있습니다. –

1

또는에서 괴물을 넣어 대신 벡터

하거나 벡터에 있어야하는 경우 벡터 인덱스

0

에 ID의 인덱스 맵, 즉지도를 작성의지도 이것은 공단입니다 te 샘플은 Johannes Schaub (boost 버전)의 대답을 기반으로합니다.

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