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

使用std::find_if遍历multimap时与functor配合出现错误

问题分析与解决方案

咱们先拆解你遇到的编译错误原因,再给出针对性的修复方案:

第一个版本代码的核心问题

你的std::multimap<int, int>存储的元素类型是std::pair<const int, int>,但自定义的EqualFunctor<int>::operator()接受的参数是std::pair<const int, int*>——这两个类型完全不匹配,编译器找不到合适的重载函数来调用,于是抛出了no match for call错误。简单说就是:你给functor传了一个它不认识的类型。

第二个版本代码的问题

你修改了pair的类型为std::pair<const int, int*>,但multimap的类型还是std::multimap<int, int>(它的元素类型是std::pair<const int, int>),插入std::pair<const int, int*>会导致类型不兼容(int*无法隐式转换为int);同时你的functor依然只接受std::pair<const int, int*>,和multimap实际存储的元素类型还是不匹配,所以报错依旧。

下面根据你的预期输出(显示0),给出两种可行的修复方案:


方案1:Multimap存储int值(符合你的预期需求)

如果你只是想查找second值等于0的元素,完全不需要用指针,直接比较值即可。修改functor使其匹配multimap的元素类型:

#include <iostream>
#include <algorithm>
#include <iterator>
#include <map>

template <typename T>
class EqualFunctor {
    T target_;  // 存储要匹配的目标值,而非指针
public:
    EqualFunctor(T target) : target_(target) {}
    // 参数匹配multimap的元素类型:std::pair<const int, T>
    bool operator() (const std::pair<const int, T>& myPair) {
        return myPair.second == target_;
    }
};

int main() {
    int f = 0, g = 1, h = 0, i = 1, j = 1;
    std::pair<const int, int> myPairA (1, f), myPairB (2, g), myPairC (3, h), myPairD (4, i), myPairE (5, j);
    std::multimap<int, int> myMultimap;
    myMultimap.insert(myPairB);
    myMultimap.insert(myPairC);
    myMultimap.insert(myPairD);
    myMultimap.insert(myPairE);
    
    std::multimap<int, int>::iterator it;
    // 直接传入要匹配的值0,无需指针
    it = std::find_if(myMultimap.begin(), myMultimap.end(), EqualFunctor<int>(f));
    
    if (it != myMultimap.end()) {  // 必须检查迭代器是否合法,避免访问空元素
        std::cout << it->second << std::endl;  // 输出0,符合预期
    } else {
        std::cout << "Element not found" << std::endl;
    }
    
    return 0;
}

方案2:Multimap存储int指针(若你确实需要存储指针)

如果你必须在multimap中存储指针,需要同步修改multimap的类型、插入元素的类型,以及functor的参数匹配:

#include <iostream>
#include <algorithm>
#include <iterator>
#include <map>

template <typename T>
class EqualFunctor {
    T* target_ptr_;  // 存储要匹配的目标指针
public:
    EqualFunctor(T* target_ptr) : target_ptr_(target_ptr) {}
    // 参数匹配multimap的元素类型:std::pair<const int, T*>
    bool operator() (const std::pair<const int, T*>& myPair) {
        return myPair.second == target_ptr_;
    }
};

int main() {
    int f = 0, g = 1, h = 0, i = 1, j = 1;
    int* ptrF = &f, *ptrG = &g, *ptrH = &h, *ptrI = &i, *ptrJ = &j;
    
    // 声明pair时使用int*作为second类型
    std::pair<const int, int*> myPairA (1, ptrF), myPairB (2, ptrG), myPairC (3, ptrH), myPairD (4, ptrI), myPairE (5, ptrJ);
    // 修改multimap类型为<int, int*>
    std::multimap<int, int*> myMultimap;
    myMultimap.insert(myPairB);
    myMultimap.insert(myPairC);
    myMultimap.insert(myPairD);
    myMultimap.insert(myPairE);
    
    std::multimap<int, int*>::iterator it;
    // 传入要匹配的指针
    it = std::find_if(myMultimap.begin(), myMultimap.end(), EqualFunctor<int>(myPairA.second));
    
    if (it != myMultimap.end()) {
        std::cout << *(it->second) << std::endl;  // 解引用指针得到0,符合预期
    } else {
        std::cout << "Element not found" << std::endl;
    }
    
    return 0;
}

额外简化建议:使用Lambda表达式

在C++11及以后的版本中,你可以用Lambda替代自定义functor,代码会更简洁易读:
对于方案1,std::find_if可以直接写成:

it = std::find_if(myMultimap.begin(), myMultimap.end(),
    [f](const std::pair<const int, int>& elem) {
        return elem.second == f;
    });

这样就不需要单独定义EqualFunctor类了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 10:09:36