stl - funcion - ¿Cómo usar std:: find/std:: find_if con un vector de objetos de clase personalizados?
vector find c++ (6)
Tengo una clase que representa a un usuario llamado Nick
y quiero usar std::find_if
, donde quiero saber si el vector de la lista de usuarios tiene un objeto incluido con el mismo nombre de usuario que paso. Hice algunos intentos intentando crear un nuevo objeto Nick
para el nombre de usuario que quiero probar y sobrecargar el == operator
y luego tratar de usar find/find_if
en el objeto:
std::vector<Nick> userlist;
std::string username = "Nicholas";
if (std::find(userlist.begin(), userlist.end(), new Nick(username, false)) != userlist.end())) {
std::cout << "found";
}
He sobrecargado el == operator
por lo que comparar Nick == Nick2 debería funcionar, pero la función devuelve el error C2678: binary ''=='' : no operator found which takes a left-hand operand of type ''Nick'' (or there is no acceptable conversion)
.
Aquí está mi clase de Nick como referencia:
class Nick {
private:
Nick() {
username = interest = email = "";
is_op = false;
};
public:
std::string username;
std::string interest;
std::string email;
bool is_op;
Nick(std::string d_username, std::string d_interest, std::string d_email, bool d_is_op) {
Nick();
username = d_username;
interest = d_interest;
email = d_email;
is_op = d_is_op;
};
Nick(std::string d_username, bool d_is_op) {
Nick();
username = d_username;
is_op = d_is_op;
};
friend bool operator== (Nick &n1, Nick &n2) {
return (n1.username == n2.username);
};
friend bool operator!= (Nick &n1, Nick &n2) {
return !(n1 == n2);
};
};
Debe definir el operador == con dos Objetos fuera de su clase, como una función de herramienta, no como un miembro.
Luego, para hacerlo amigo, simplemente ponga la declaración de la función dentro de la clase.
prueba algo como esto:
class Nick {
public:
friend bool operator== ( const Nick &n1, const Nick &n2);
};
bool operator== ( const Nick &n1, const Nick &n2)
{
return n1.username == n2.username;
}
También su hallazgo debe verse así:
std::find(userlist.begin(), userlist.end(), Nick(username, false) );
No hay necesidad de "nuevo".
Estás pasando un puntero a la función de búsqueda. Suelta el nuevo:
std::find(userlist.begin(), userlist.end(), Nick(username, false))
Además, sus operadores deben aceptar sus argumentos por referencia constante, no los modifican.
bool operator== (const Nick &n1, const Nick &n2)
Estoy notando que estás tratando de llamar a un constructor de otro de esta manera:
Nick(std::string d_username, bool d_is_op) {
Nick();
...
Bueno, lo siento, pero esto no funciona. La línea Nick()
simplemente crea un temporal y no afecta this
. El reenvío de constructor solo es posible en C ++ 0x (el próximo estándar)
En cuanto a su problema, esta pregunta formulada hace un par de días sobre binary_search cubre los mismos motivos. La respuesta principal es simplemente impresionante.
Restricción mística en std :: binary_search
HTH.
PS Idealmente, esto debería haber sido un comentario, pero es demasiado detallado
Puedes usar boost :: bind
std::find_if( userlist.begin(), userlist.end(),
boost::bind( & Nick::isFound,
_1 ) );
solo implementa bool Nick :: isFound ()
También puedes pasar los criterios.
std::find_if( userlist.begin(), userlist.end(),
boost::bind( & Nick::compare,
_1,
nick ) );
implementar
bool Nick::compare( const Nick & nick )
{
return this->username == nick.username;
}
Sé que quería sobrecargar el operador ==
, pero lo mismo se puede hacer fácilmente con un predicado:
struct UsernameIs {
UsernameIs( string s ) : toFind(s) { }
bool operator() (const Nick &n)
{ return n.username == toFind; }
string toFind;
};
int main()
{
vector<Nick> vn(10);
string nameToFind = "something";
find_if(vn.begin(), vn.end(), UsernameIs(nameToFind));
}
Tenga en cuenta que en C ++ 0x, puede hacer lo mismo con una expresión lambda mucho más concisa.
Si está utilizando C ++ 0X, puede usar una expresión lambda simple
std::string username = "Nicholas";
std::find_if(userlist.begin(), userlist.end(), [username](Nick const& n){
return n.username == username;
})