2010-01-08 18 views
7

Estoy seguro de que estoy haciendo esto más difícil de lo necesario.Buscando en C++ std vector de estructuras para struct con la cadena correspondiente

Tengo un vector ...

vector<Joints> mJointsVector; 

... compuesta de estructuras siguen el modelo de los siguientes:

struct Joints 
{ 
    string name; 

    float origUpperLimit; 
    float origLowerLimit; 
}; 

Estoy tratando de buscar mJointsVector con "std :: find" para localizar una unión individual por su nombre de cadena - sin suerte hasta el momento, pero los ejemplos de los siguientes han ayudado, al menos conceptualmente:

Vectors, structs and std::find

¿Alguien puede indicarme más en la dirección correcta?

+1

Si bien las respuestas a continuación son muy bien, suena como el uso que usted debe utilizar un 'map' lugar, del' 'string' a Joints' . Esto también mejorará los tiempos de búsqueda. – GManNickG

+0

Creo que probablemente tengas razón, tendré que investigar esto más adelante. –

+0

¡Guau, los mapas y las multimapas * son * geniales! ¡Especialmente con * for_each * usando objetos de función en lugar de bucles! http://www.codeproject.com/KB/stl/replace_for_each.aspx?display=Print Tan útil para poder "reutilizar" el código de bucle de esta manera. –

Respuesta

16

A-forward-aproximación directa:

struct FindByName { 
    const std::string name; 
    FindByName(const std::string& name) : name(name) {} 
    bool operator()(const Joints& j) const { 
     return j.name == name; 
    } 
}; 

std::vector<Joints>::iterator it = std::find_if(m_jointsVector.begin(), 
               m_jointsVector.end(), 
               FindByName("foo")); 

if(it != m_jointsVector.end()) { 
    // ... 
} 

Alternativamente, usted puede que desee ver en algo así como Boost.Bind para reducir la cantidad de código.

+2

mientras esto funciona, creo que el operador() de un objeto de función siempre debe ser const, solo por flexibilidad. si un día tiene un rango de juntas de const, el objeto de función aún funciona. – vividos

+0

Esto solo parece funcionar si cambio "bool operator (" a "bool operator() (". ¿Es esto correcto? Estoy abrumado por la cantidad de maneras de hacerlo! –

+0

Vaya, me perdí la primera paréntesis - fijo –

0
bool 
operator == (const Joints& joints, const std::string& name) { 
    return joints.name == name; 
} 

std::find(mJointsVector.begin(), mJointsVector.end(), std::string("foo")); 
1

Usted debe ser capaz de añadir un operador de igualdad Haga su estructura

struct Joints 
{ 
    std::string name; 

    bool operator==(const std::string & str) { return name == str; } 
}; 

A continuación, puede buscar utilizando hallazgo.

+0

El operador de igualdad debe reservarse para su uso para probar si dos objetos del mismo tipo son equivalentes. Muy rara vez debería usarlo para comparar con otros tipos. –

+0

¿Explicar por qué o citar una fuente que lo hace? –

+0

Esta respuesta corta simple tiene muchas deficiencias: usted debería preferir operadores de funciones libres sobre operadores de función miembro (simetría con respecto a los tipos en algunas operaciones), si sobrecarga == también deberías sobrecargar! =, y finalmente, como apuntó Martin, al sobrecargar a un operador no deberías cambiar la semántica. El símbolo del operador implica cierta semántica para el lector; si esa semántica se rompe, la posibilidad de errores en el código del usuario aumenta.¿Quién podría pensar que 'a == b' arrojaría verdadero para diferentes objetos? –

5

¿qué tal:

std::string name = "xxx"; 

std::find_if(mJointsVector.begin(), 
      mJointsVector.end(), 
      [&s = name](const Joints& j) -> bool { return s == j.name; }); 
+0

Uh, ¿qué? Esto aún no es compatible: P (Incluso entonces, creo que esto está mal.) – GManNickG

+7

No está mal, es correcto y en un par de años, esta respuesta se verá como "más" correcta en comparación con los demás . –

+0

Darid, ¿qué quieres decir? ¿Por qué es esto más correcto? No te estoy desafiando, estoy totalmente desorientado, y curioso. –

0
struct Compare: public unary_function <const string&> 
{ 
    public: 
      Compare(string _findString):mfindString(_findString){} 
      bool operator() (string _currString) 
      { 
       return _currString == mfindString ; 
      } 
    private: 
      string mfindString ; 
} 

std::find_if(mJointsVector.begin(), mJointsVector.end(), Compare("urstring")) ; 
+0

Nunca ha declarado '_currString' o' _findString' y su herencia es incorrecta (precise los parámetros de la plantilla) –

+0

Gracias por señalarlo. Lo he corregido – mukeshkumar

1
#include <boost/bind.hpp> 

std::vector<Joints>::iterator it; 

it = std::find_if(mJointsVector.begin(), 
        mJointsVector.end(), 
        boost::bind(&Joints::name, _1) == name_to_find); 
Cuestiones relacionadas