29

我有一个代表用户的类Nick,我想std::find_if在它上面使用,我想在其中查找用户列表向量是否包含与我传入的相同用户名的对象。我尝试Nick为我要测试并重载== operator然后尝试find/find_if在对象上使用的用户名:

    std::vector<Nick> userlist;
    std::string username = "Nicholas";

if (std::find(userlist.begin(), userlist.end(), new Nick(username, false)) != userlist.end())) {
    std::cout << "found";
}

我已经重载了== operator所以比较 Nick == Nick2 应该可以工作,但是函数返回error C2678: binary '==' : no operator found which takes a left-hand operand of type 'Nick' (or there is no acceptable conversion).

这是我的尼克课程供参考:

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);
    };
};
4

7 回答 7

41

如果您使用的是 C++0X,则可以使用简单的 lambda 表达式

std::string username = "Nicholas";    
std::find_if(userlist.begin(), userlist.end(), [username](Nick const& n){
    return n.username == username;
})
于 2011-08-04T09:49:41.467 回答
19

您必须使用类外部的两个对象定义 operator== 作为工具函数,而不是成员。

然后让它成为朋友,只需将函数的声明放在类中。

尝试这样的事情:

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;
}

你的发现也应该是这样的:

std::find(userlist.begin(), userlist.end(), Nick(username, false) );

不需要“新”。

于 2011-08-04T09:49:02.857 回答
9

I know that you wanted to overload the == operator, but the same thing can easily be done with a predicate:

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));
}

Note that in C++0x, you can do the same thing with a lambda expression much more concisely.

于 2011-08-04T09:54:50.830 回答
3

You are passing a pointer to the find function. Drop the new:

std::find(userlist.begin(), userlist.end(), Nick(username, false))

Also, your operators should accept their arguments by const reference, they don't modify them.

bool operator== (const Nick &n1, const Nick &n2)
于 2011-08-04T09:42:57.647 回答
1

You can use boost::bind

std::find_if( userlist.begin(), userlist.end(),
            boost::bind( & Nick::isFound,
                         _1 ) );

just implement bool Nick::isFound()

You can also pass the criteria

std::find_if( userlist.begin(), userlist.end(),
              boost::bind( & Nick::compare,
                           _1,
                           nick ) );

implement

bool Nick::compare( const Nick & nick )
{
    return this->username == nick.username;
}
于 2011-08-04T09:45:53.903 回答
1

我注意到您正试图以这种方式从另一个构造函数调用一个构造函数:

Nick(std::string d_username, bool d_is_op) {
        Nick();
 ...

好吧,对不起,但这不起作用。该行Nick()只是创建一个临时的并且不影响this. 构造函数转发只能在 C++0x(即将推出的标准)中实现

至于您的问题 - 几天前提出的关于 binary_search 的这个问题涵盖了相同的理由。最佳答案真是太棒了。

对 std::binary_search 的神秘限制

HTH。

PS 理想情况下,这应该是一个评论,但它太冗长了

于 2011-08-04T09:47:01.127 回答
0

这对我有用:

尼克

#include <string>

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;
    };

    bool operator==(const Nick& refNick) const
    {
        if (username != refNick.username)
            return false;
        if (interest != refNick.interest)
            return false;
        if (email != refNick.email)
            return false;
        if (is_op != refNick.is_op)
            return false;
        return true;
    }

    bool operator!=(const Nick& refNick) const
    {
        if (username == refNick.username)
            return true;
        if (interest == refNick.interest)
            return true;
        if (email == refNick.email)
            return true;
        if (is_op == refNick.is_op)
            return true;
        return false;
    }
};

主文件

#include <iostream>
#include <string>
#include <vector>
#include "Nick.h"

int main()
{
    std::vector<Nick> userlist;
    std::string username = "Nicholas";    
    Nick Nicholas(username, false);
    Nick John("John", true);        
    userlist.push_back(Nicholas);

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

    it = std::find(userlist.begin(), userlist.end(), Nick("Nicholas", false));
    if(it != userlist.end())
        std::cout << "\n" << Nicholas.username << " was found.";
    else
        std::cout << "\n" << Nicholas.username << " was not found.";

    it = std::find(userlist.begin(), userlist.end(), John);
    if (it != userlist.end())
        std::cout << "\n" << John.username << " was found.";
    else
        std::cout << "\n" << John.username << " was not found.";
}

结果

Nicholas was found.
John was not found.
于 2021-11-17T06:10:16.430 回答