8

オーバーロードされた operator==() を使用してベクター内の要素を見つけようとしています。ただし、type1次のコードで使用すると、出力は 1 と 0 (見つかりません) になります。Usingtype2は 1 と 1 の両方を返します。環境は Xubuntu 12.04 と g++ バージョン 4.6.3 です。

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

typedef pair<string, int> type1;
struct type2: public type1 {};
#define TYPE type1

bool operator== (const TYPE& lhs, const TYPE& rhs) {
    return lhs.first == rhs.first;
}

int main()
{
    vector<TYPE> vec;
    TYPE v1, v2;

    v1.first = "abc"; v1.second = 1; vec.push_back(v1);
    v2.first = "abc"; v2.second = 2;

    cout << (v1 == v2) << endl;
    cout << (find(vec.begin(), vec.end(), v2) != vec.end()) << endl;
}
4

4 に答える 4

8

std::pairこれは、とフィールドの両方を比較して、任意のペアのテンプレートoperator==です。この演算子は、4 つのケースのいずれか、つまりwith で選択されます。ただし、詳細は少し複雑です。stdfirstsecondfindTYPE == type1

実際に何が起こるかTYPE == type1は(間違っている場合は修正してください)

  • for v1 == v2ADL ( Argument Dependent Name Lookup ) が適用されて in が検索されますoperator==stdつまり、この演算子は通常のオーバーロード セットに追加されます。ただし、現在の翻訳単位の非テンプレート バージョンは、 のテンプレートoperator==よりも引き続き優先されstdます。
  • std::find呼び出しは 内でインスタンス化されるため、のstdルックアップは でoperator==直接開始されstdます。(ADL を使用せずに) 1 つの一致が検出されるため、OP 自体の演算子が含まれていたはずの外側のスコープは検索されません。

そして、TYPE == type2

  • v1 == v2operator==簡単です-それは、囲んでいる名前空間で を直接見つけます。
  • std::findも でインスタンス化されますがstd、メイン スコープのカスタム オペレータは、ADL を使用して設定されたオーバーロード解決に追加され、次に でのものよりも具体的であることがわかりますstd
于 2013-10-04T18:00:57.023 に答える
1

findの代わりにfind_ifを使用した方がよいと思います。述語を取るので、比較子を通常の関数/ファンクターとして定義して渡すことができます。

于 2013-10-04T18:09:20.193 に答える
1

std::pairoperator==自分自身よりも優先される独自のものがあります。

于 2013-10-04T18:01:32.197 に答える