You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何std::find未调用我重载的std::pair<int,int>的operator==?

问题:重载std::pair的operator==后std::find未调用自定义逻辑

尝试重载std::pair<int,int>的operator==,使其仅比较pair的第一个元素,期望std::find在std::vector<std::pair<int,int>>中查找时调用该重载,但实际仅直接比较语句有效,std::find未使用自定义逻辑。

预期输出:

1
1
1

实际输出:

1
1
0

运行环境:Linux、gcc 11.3

代码如下:

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

using namespace std;

typedef pair<int, int> p_int_t;

bool operator==(const p_int_t& p1, const p_int_t& p2)
{
    return p1.first == p2.first;
}

int main()
{
    vector<p_int_t> v;

    v.push_back({1, 2});
    v.push_back({1, 3});

    p_int_t p(1, 4);

    cout << (v[0] == p) << endl;
    cout << (v[1] == p) << endl;

    cout << (find(v.begin(), v.end(), p) != v.end()) << endl;

    return 0;
}

原因分析

  1. 直接比较的逻辑:代码中使用了using namespace std;,全局命名空间的自定义operator==和std命名空间的默认operator==都在作用域内。由于自定义的operator==是非模板函数,而标准库的std::operator==是模板函数,重载决议时非模板函数优先级更高,所以直接比较时会调用自定义逻辑。
  2. std::find的逻辑:std::find是std命名空间中的函数,在其内部执行比较操作时,会优先通过依赖于参数的查找(ADL)搜索参数类型所在的std命名空间,找不到全局命名空间的自定义重载,因此使用了标准库默认的operator==——该逻辑要求pair的两个元素都相等才返回true。示例中p的第二个元素是4,与vector中元素的第二个元素不匹配,所以std::find找不到匹配项,输出0。

解决方案

方案1:使用std::find_if+自定义谓词(推荐)

避免重载标准库类型的operator==,改用std::find_if并传入自定义lambda作为匹配条件,这是更安全、符合标准的做法:

修改后的代码:

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

using namespace std;

typedef pair<int, int> p_int_t;

int main()
{
    vector<p_int_t> v;

    v.push_back({1, 2});
    v.push_back({1, 3});

    p_int_t p(1, 4);

    cout << (v[0].first == p.first) << endl;
    cout << (v[1].first == p.first) << endl;

    auto it = find_if(v.begin(), v.end(), [&p](const p_int_t& elem) {
        return elem.first == p.first;
    });
    cout << (it != v.end()) << endl;

    return 0;
}

方案2:将重载放入std命名空间(不推荐)

虽然C++标准禁止用户向std命名空间添加自定义内容,但部分编译器(如gcc)会允许这种操作。将自定义的operator==放入std命名空间后,ADL就能找到它:

修改后的代码片段:

namespace std {
bool operator==(const pair<int, int>& p1, const pair<int, int>& p2)
{
    return p1.first == p2.first;
}
} // namespace std

注意:此方法属于未定义行为,可能在不同编译器或版本中出现问题,不建议在生产代码中使用。

内容的提问来源于stack exchange,提问作者sarzynek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 11:31:05