web-dev-qa-db-ja.com

ベクトル、構造体、およびstd :: find

再び私とベクトル。迷惑にならないことを願っています。私はこのような構造体を持っています:

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要素のみを反復処理したいのですが、その方法がわかりません。ヘルプは大歓迎です。よろしくお願いします!

30
Ahmed

std::find_if

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

または、ブーストがない場合は、独自の関数オブジェクトを作成します。このようになります

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));

独自の検索述語を記述する必要があります。

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));
16
Evgeny Lazin

どうですか:

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

std::findテンプレート、特に3番目のパラメーターを見てください。

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

このEqualityComparableとは何ですか?再びドキュメントから:

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

さて、あなたのタイプモンスターはそのような演算子を定義する必要があります。コンパイラーが生成しない場合(デフォルトのctorとdtorとしても)、コンパイラーはmemcmpの種類の処理を実行します。したがって、std::findを使用するには、最初に、アルゴリズムがcurrentMonsterに一致させるために使用できるコンパレーター関数/ファンクターを定義します。

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

またはモンスターをベクトルの代わりにマップに配置する

または、それらがベクトル内になければならない場合は、インデックスマップ、つまりIDとベクトルインデックスのマップを作成します。

1
pm100

これはヨハネスシャウブ(ブーストバージョン)の回答に基づく完全なサンプルです。

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