2009-02-26 20 views
22

De nuevo conmigo con vectores. Espero no ser tan molesto Tengo una estructura como esta:Vectores, estructuras y std :: encontrar

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

Así que creó un vector:

std::vector<monster> monsters; 

Pero ahora no sé cómo buscar a través del vector. Quiero encontrar una identificación del monstruo dentro del vector.

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

Pero obviamente no funciona. Quiero iterar solo a través del elemento .id de la estructura, y no sé cómo hacer eso. La ayuda es muy apreciada. Gracias !

Respuesta

33

std::find_if:

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

O escribir su propio objeto de la función si no tiene impulso. Se vería así

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

usando boost, ¡perfecto! –

+0

Me pregunto, si tengo '{int, int}', ¿podría convertirlo a 'long' y usar normal find then? –

+1

¿Cuál es el significado de "bot" en bot.monsters.begin()? –

13

tiene que escribir su propio predicado de búsqueda:

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

Una respuesta agradable, pero hay un error tipográfico en el constructor. Debería ser ':' no ';' –

+0

Además de escribir su propio predicado de búsqueda, necesita usar 'std :: find_if' en lugar de' std :: find'. –

7

Tome un vistazo a la plantilla std::find, el tercer parámetro en especial:

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

¿Qué es esto EqualityComparable? De nuevo desde la documentación:

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

Ahora, su monstruo tipo necesita definir dicho operador. Si no lo hace, el compilador generará uno para usted (como también el ctor predeterminado y el dtor) que hace un tipo de cosa que no funciona en su caso memcmp. Por lo tanto, para utilizar std::find primero definir una función de comparación/funtor que el algoritmo puede utilizar para que coincida con su currentMonster decir algo en la línea de:

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

¿Esto funciona? No tuve éxito porque una definición de operador dentro de una estructura solo puede tener 1 entrada –

+0

Mismo problema que Snoozer. -1, por favor complete la respuesta. –

7

¿qué tal:

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

¿Alguien que vea esto me guiará por lo que está haciendo?Específicamente el [& cm = currentMonster] (const monstruo & m) -> bool {return cm == m; }); – 2kreate

+2

Este ejemplo usa una función lambda, que depende de C++ 11. '[& cm = currentMonster]' vincula la variable 'currentMonster' del ámbito de llamada a una referencia local en el lambda, llamada' cm'. Luego '(const monster & m) -> bool' define la firma de la lambda, tomando un parámetro de entrada,' m', y devolviendo 'bool'. El cuerpo de la función lambda es '{return cm == m; } ', devuelve true si' cm' y 'm' se comparan como iguales. –

+0

Finalmente sé cómo vincular adecuadamente las variables locales a lambdas. –

1

o poner los monstruos en un mapa en lugar de un vector

o si deben estar en un vector de crear un mapa de mapa de índice es decir de ID de índice de vector

0

Este es un comple la muestra basada en la respuesta de Johannes Schaub (versión de refuerzo).

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