J'ai une classe représentant un utilisateur appelé Nick
et je veux utiliser std::find_if
Dessus, où je veux trouver si le vecteur de la liste d'utilisateurs a un objet inclus avec le même nom d'utilisateur que je passe. I a fait quelques tentatives en essayant de créer un nouvel objet Nick
pour le nom d'utilisateur que je veux tester et en surchargeant le == operator
, puis en essayant d'utiliser find/find_if
sur l'objet:
std::vector<Nick> userlist;
std::string username = "Nicholas";
if (std::find(userlist.begin(), userlist.end(), new Nick(username, false)) != userlist.end())) {
std::cout << "found";
}
J'ai surchargé le == operator
Donc comparer Nick == Nick2 devrait fonctionner, mais la fonction retourne error C2678: binary '==' : no operator found which takes a left-hand operand of type 'Nick' (or there is no acceptable conversion)
.
Voici ma classe Nick pour référence:
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);
};
};
Vous devez définir l'opérateur == avec deux objets en dehors de votre classe, en tant que fonction d'outil, pas en tant que membre.
Ensuite, pour le rendre ami, mettez simplement la déclaration de la fonction dans la classe.
essayez quelque chose comme ceci:
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;
}
Votre recherche devrait également ressembler à ceci:
std::find(userlist.begin(), userlist.end(), Nick(username, false) );
Pas besoin de "nouveau".
Si vous utilisez C++ 0X, vous pouvez utiliser une simple expression lambda
std::string username = "Nicholas";
std::find_if(userlist.begin(), userlist.end(), [username](Nick const& n){
return n.username == username;
})
Je sais que tu voulais surcharger le ==
, mais la même chose peut facilement être faite avec un prédicat:
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));
}
Notez qu'en C++ 0x, vous pouvez faire la même chose avec une expression lambda de manière beaucoup plus concise.
Vous passez un pointeur sur la fonction de recherche. Déposez le nouveau:
std::find(userlist.begin(), userlist.end(), Nick(username, false))
De plus, vos opérateurs doivent accepter leurs arguments par référence const, ils ne les modifient pas.
bool operator== (const Nick &n1, const Nick &n2)
Je remarque que vous essayez d'appeler un constructeur d'un autre de cette manière:
Nick(std::string d_username, bool d_is_op) {
Nick();
...
Eh bien, désolé, mais cela ne fonctionne pas. La ligne Nick()
crée juste un temporaire et n'affecte pas this
. Le transfert de constructeur n'est possible qu'en C++ 0x (la norme à venir)
Quant à votre problème - cette question posée il y a quelques jours à propos de binary_search couvre les mêmes motifs. La meilleure réponse est tout simplement géniale.
Restriction mystique sur std :: binary_search
HTH.
P.S. Idéalement, cela aurait dû être un commentaire, mais il est tout simplement trop verbeux
Vous pouvez utiliser boost :: bind
std::find_if( userlist.begin(), userlist.end(),
boost::bind( & Nick::isFound,
_1 ) );
implémentez simplement bool Nick :: isFound ()
Vous pouvez également passer les critères
std::find_if( userlist.begin(), userlist.end(),
boost::bind( & Nick::compare,
_1,
nick ) );
mettre en place
bool Nick::compare( const Nick & nick )
{
return this->username == nick.username;
}