Векторы, структуры и std:: find
Снова меня с векторами. Надеюсь, я не слишком раздражаю. У меня есть такая структура:
struct monster
{
DWORD id;
int x;
int y;
int distance;
int HP;
};
Итак, я создал вектор:
std::vector<monster> monsters;
Но теперь я не знаю, как искать вектор. Я хочу найти идентификатор монстра внутри вектора.
DWORD monster = 0xFFFAAA;
it = std::find(bot.monsters.begin(), bot.monsters.end(), currentMonster);
Но, очевидно, это не сработает. Я хочу выполнять итерацию только через .id-элемент структуры, и я не знаю, как это сделать. Помощь очень ценится. Спасибо!
Ответы
Ответ 1
std::find_if
:
it = std::find_if(bot.monsters.begin(), bot.monsters.end(),
boost::bind(&monster::id, _1) == currentMonster);
Или напишите свой собственный объект функции, если у вас нет boost. Будет выглядеть так:
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));
Ответ 2
Вам нужно написать собственный предикат поиска:
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));
Ответ 3
как насчет:
std::find_if(monsters.begin(),
monsters.end(),
[&cm = currentMonster]
(const monster& m) -> bool { return cm == m; });
Ответ 4
Взгляните на шаблон std::find
, особенно третий параметр:
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
i.e, что-то вроде строк:
struct monster {
// members
bool operator==(const monster& l, const monster& r) const
{
return l.id == r.id;
}
};
Ответ 5
или поместите монстров в карту вместо вектора
или если они должны быть в векторе, создайте карту индексов, то есть карту идентификатора к векторному индексу
Ответ 6
Это полный образец, основанный на ответе Йоханнеса Шауба (ускоренная версия).
#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;
}
Ответ 7
Вы можете написать функцию, как показано ниже:
monster* findMonster(DWORD currentMonster) {
for (auto it = bot.monsters.begin(); it != bot.monsters.end(); it++) {
if (it->id == currentMonster) {
return &(*it);
}
}
return NULL;
}
Возвращает указатель на сохраненный узел, если он найден в векторе, в противном случае возвращает NULL.
Обратите внимание, что return it;
не будет работать напрямую.