29

と呼ばれるユーザーを表すクラスがあり、そのクラスでNick使用std::find_ifしたいのですが、userlistベクトルに、渡したのと同じユーザー名のオブジェクトが含まれているかどうかを確認します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)

参考までに、私のNickクラスは次のとおりです。

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を使用している場合は、単純なラムダ式を使用できます

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

メンバーではなくツール関数として、クラス外の2つのオブジェクトで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

演算子をオーバーロードしたかったことは知っていますが==、述語を使用して同じことを簡単に行うことができます。

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

C ++ 0xでは、ラムダ式を使用して同じことをはるかに簡潔に実行できることに注意してください。

于 2011-08-04T09:54:50.830 に答える
3

検索関数へのポインタを渡しています。新しいものをドロップします:

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

また、演算子はconst参照によって引数を受け入れる必要があり、変更はしません。

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

boost::bindを使用できます

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

bool Nick :: isFound()を実装するだけです

基準に合格することもできます

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

埋め込む

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

これは私のために働きます:

Nick.h

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

main.cpp

#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 に答える