2011-05-03 17 views
7

Estoy usando un conjunto para contener las estructuras que contienen varias cadenas. Quiero poder usar la funcionalidad find() de los conjuntos. Sin embargo, dado que el conjunto contiene estructuras, no funciona. Quiero find() para mirar una de las cadenas en la estructura cuando encuentra. ¿Cómo puede hacerse esto?Haciendo que encontrar trabajo con un conjunto de estructuras

Aquí está el código que traté de usar. Funciona bien, excepto en la parte donde se usa find().

#include <iostream> 
#include <string> 
#include <set> 
using namespace std; 

struct test 
{ 
    string key; 
    string data; 
}; 

bool operator<(const test & l, const test & r) 
{ 
    return l.key < r.key; 
} 

bool operator==(const test & l, const test & r) 
{ 
    return l.key == r.key; 
} 

set<test> s; 

int main() 
{ 
    test newmember; 
    newmember.key = "key"; 
    newmember.data = "data"; 
    s.insert(newmember); 
    s.find("key"); 
} 

Éstos son los mensajes de error cuando intento compilar:

test.cpp:30:7: error: no matching member function for call to 'find' 
    s.find("key"); 
    ~~^~~~ 
In file included from test.cpp:3: 
In file included from /usr/include/c++/4.2.1/set:65: 
/usr/include/c++/4.2.1/bits/stl_set.h:429:7: note: candidate function not viable: no known conversion from 'const char [4]' to 'const key_type' (aka 'const test') for 1st argument 
     find(const key_type& __x) 
    ^
/usr/include/c++/4.2.1/bits/stl_set.h:433:7: note: candidate function not viable: no known conversion from 'const char [4]' to 'const key_type' (aka 'const test') for 1st argument 
     find(const key_type& __x) const 
    ^
1 error generated. 

Respuesta

2

Para poder poner sus estructuras en set, debe especificar operator< para su estructura. Puede hacer que el resultado de devolución operator< compare los miembros de cadena correspondientes.

Para poder usar find puede especificar operator== para que su estructura devuelva true si los miembros de cadena correspondientes son iguales.

muestra:

// code from your question used here 

    int main() 

{ 
    test newmember; 
    newmember.key = "key"; 
    newmember.data = "data"; 

    test findMember; 
    findMember.key = "key"; 
    // as operator== and operator< doesn't care about data field we can left it be 
    // initialized by default constructor 

    s.insert(newmember); 
    s.find(findMember); 
} 

Si desea llamar find() con string parámetro que puede proporcionar un constructor implícito de string para su test estructura, por ejemplo, así:

struct test { 
//... 
    test(const string &in_key) : key(in_key) {} 
//... 
}; 

Pero el uso del implícita constructores no es una buena técnica, ya que puede conducir a algunas conversiones impredecibles en algún lugar más allá en su código.

+0

¿Cuál es el código para hacer eso? Puedo sobrecargar el operador

+0

@ z-buffer: vea la versión actualizada de mi respuesta. Tu problema es que debes proporcionar 'find()' con instancia de tu estructura 'test'. – beduin

11

Sugiero operator< y operator== a su estructura en lugar de sobrecargar el operador global, me parece mucho más limpio; ejemplo:

struct test 
{ 
    string key; 
    string data; 

    bool operator<(const test& rhs) const 
    { 
    return key < rhs.key; 
    } 

    bool operator==(const test& rhs) const 
    { 
    return key == rhs.key; 
    } 
}; 

Ahora a su problema real - su están pasando una cadena a la función find(), pero sólo acepta estructuras de tipo test. Con el fin de hacerlo, añada un constructor para la conversión automática, por lo que la estructura final sería el siguiente aspecto:

struct test 
{  
    string key; 
    string data; 

    test(const std::string& strKey = "", const std::string& strData = "") 
    : key(strKey), 
    data(strData) {} 

    bool operator<(const test& rhs) const 
    { 
    return key < rhs.key; 
    } 

    bool operator==(const test& rhs) const 
    { 
    return key == rhs.key; 
    } 
}; 

A continuación, pasar una cadena a find() se llamará automáticamente al constructor y crear un test estructura temporal que contiene sólo el relevante llave. Tenga en cuenta que en este caso especial, el constructor no debe declararse explicit.

Cuestiones relacionadas