【问题标题】:Does std::find use operator== for std::vector<std::pair<T, T>>?std::find 是否对 std::vector<std::pair<T, T>> 使用 operator==?
【发布时间】:2023-02-16 20:51:56
【问题描述】:

我试图为 std::pair<int, int> 重载 operator== ,这样只有该对的第一个元素才重要。然后,我想使用 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;
}

【问题讨论】:

    标签: iterator find std operator-keyword predicate


    【解决方案1】:

    编译器不选择独立的比较运算符,因为类型 p_int_t 是一个别名,并且它没有像 std:: pair 那样在 std 命名空间中定义。换句话说,编译器正在寻找具有此签名的运算符:std::operator==(const std::pair&lt;int, int&gt;&amp;, const std::pair&lt;int, int&gt;&amp;); 并在algorithm 中找到它。

    您可以在 std 命名空间中声明您的运算符,这可行,但不推荐,或者将 p_int_t 定义为一个类,如下所示:

    #include <algorithm>
    #include <iostream>
    #include <utility>
    #include <vector>
    
    using namespace std;
    
    struct p_int_t : pair<int, int> {
    
        using pair<int, int>::pair;   // for c++=11 and later
    
        p_int_t() : pair() {}                 // for c++98
        p_int_t(int x, int y) : pair(x, y) {} // for c++98
    
        friend 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;
    }
    

    代码可以在这里找到:https://godbolt.org/z/5dfPaaoMz

    必须重新定义构造函数非常麻烦,但您也可以使用 std::find_if(),如:

    #include <algorithm>
    #include <iostream>
    #include <utility>
    #include <vector>
    
    using namespace std;
    
    typedef pair<int, int> p_int_t;
    
    struct compare_first {
        p_int_t p;
    
        compare_first(p_int_t x) : p(x) {}
        bool operator()(const p_int_t& x) { return x.first == p.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 << (find_if(v.begin(), v.end(), compare_first(p)) != v.end()) << endl;
    
        // or for c++11 or later...
    
        cout << (find_if(v.begin(), v.end(), [&p](const p_int_t& x) { return p.first == x.first; }) != v.end()) << endl;
         
    
        return 0;
    }
    

    代码在这里:https://godbolt.org/z/r87hdrrK9

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-02
      • 2017-09-01
      • 2019-10-20
      • 2022-11-21
      • 2016-03-31
      • 2019-11-07
      相关资源
      最近更新 更多