1

変数に関する情報、つまり名前と番号を含む構造体を作成しました

struct var{
  string name;
  int value;
};

ここで、次の関数を使用して、イテレーターを使用して更新します。

void updateVariable(vector<Variable>& vars,Variable& newVar){
    vector<Variable>::iterator it = find(vars.begin(), vars.end(), newVar);

    if(it == vars.end()){
        vars.push_back(newVar);
    }
    else{
        *it = newVar;
    }
}

念のために言っておきますが、私が得ているエラーは、find()の呼び出しの行にあります。エラーが発生する理由はありますか?エラーは次のとおりです。

/usr/include/c++/4.6/bits/stl_algo.h:162:4: error: no match for ‘operator==’ in ‘__first.__gnu_cxx::__normal_iterator<_Iterator, _Container>::operator* [with _Iterator = Variable*, _Container = std::vector<Variable>, __gnu_cxx::__normal_iterator<_Iterator, _Container>::reference = Variable&]() == __val’

アップデート:

迅速なサポートと明確な回答をありがとうございました。

4

2 に答える 2

7

operator ==構造体を定義していませんvar。アルゴリズムはfind()デフォルトoperator ==で、指定した値を指定した範囲の値と比較するために使用し、イテレータを最初の要素と比較して等しくなります。

これを修正するにoperator ==は、クラスをオーバーロードするだけです。これを行う1つの方法は次のとおりです。

struct var
{
    string name;
    int value;
};

bool operator == (var const& v1, var const& v2)
{
    return (v1.name == v2.name) && (v1.value == v2.value);
}

operator ==構造体と同じ名前空間で定義するようにしてくださいvar。そうしないと、ADL(Argument Dependent Lookup)が失敗し、コンパイラエラーが発生する可能性があります。

C ++ 11を使用していて、オーバーロードされたバージョンのをわざわざ定義したくない場合は、最後の引数としてラムダをoperator ==使用して渡すこともできます。find_if()

find_if(vars.begin(), vars.end(), [&] (var const& v) { 
    return (v.name == newVar.name) && (v.value == newVar.value);
    });

GManNickGが正しく指摘しているように、複数のメンバーを比較する必要がある場合、forを使用std::tieてオーバーロードoperator ==すると、std::tuple入力を節約できる可能性があります。

 auto const tieMembers = [] (const var&) { 
    return std::tie(v.name, v.value, ...);
    };

上記のラムダは、値v1v2タイプを比較するときにこのように使用できvarます。

return (tieMembers(v1) == tieMembers(v2));
于 2013-02-21T18:38:27.623 に答える
2

operator==forのオーバーロードを定義する必要がありますvar。これは機能するはずです。

bool operator==(const var& a, const var& b){
  return (a.name == b.name) && (a.value == b.value);
}
于 2013-02-21T18:39:48.450 に答える