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

C++自定义容器用std::find/find_if查找对象报C2064错误解决方法

错误原因

两个版本的代码分别存在逻辑错误:

  1. 第一版用std::find的逻辑不成立:std::find的匹配规则是将遍历到的容器元素直接与第三个传入值做==比较。你的容器存储的是WindowWithTitleButton类型对象,传入的待匹配值是string类型,二者没有定义对应的相等比较运算符,根本无法完成匹配。
  2. 第二版触发C2064编译错误的核心原因是std::find_if的第三个参数传参完全不符合要求:std::find_if要求第三个参数是接收1个参数(即当前遍历到的容器元素)、返回可转换为bool类型值的可调用对象。你传入的ContainsTitle((*iter).GetTitle(),title_find)是一次即时函数调用,最终传入的是该函数返回的bool类型结果,不是可调用对象;编译器拿到一个bool值自然无法将其作为函数调用,就会抛出“项不会计算为接受1个参数的函数”的错误。

另外你实现的ContainsTitle本身设计也有问题:作为类成员函数它会隐式携带this指针,不能直接作为谓词传给STL算法,且参数逻辑错误——谓词只需要接收当前遍历到的容器元素即可,不需要提前传入迭代器指向的元素值。

正确实现方案

推荐写法(C++11及以上版本)

不需要单独定义ContainsTitle函数,直接在find_if中传入lambda表达式作为谓词,代码最简洁直观:

#include <algorithm>

MyIterator<WindowWithTitleButton> WindowList::FindTitle(const string& title_find)
{   
    return std::find_if(begin(), end(), [&title_find](const WindowWithTitleButton& wnd) {
        return wnd.GetTitle() == title_find;
    });
}

lambda通过引用捕获要查找的目标title,每次遍历到窗口对象时,自动取对象的title属性和目标值比对,完全符合find_if对谓词的参数要求。

兼容旧标准写法(无C++11支持场景)

如果编译器不支持lambda,自定义仿函数(重载了()运算符的结构体)作为谓词,提前把待匹配的title存入仿函数实例即可:

// 定义为WindowList的私有内部类型,或全局匿名命名空间下的辅助类型
struct MatchWindowTitle {
    string target;
    explicit MatchWindowTitle(const string& t): target(t) {}
    bool operator()(const WindowWithTitleButton& wnd) const {
        return wnd.GetTitle() == target;
    }
};

MyIterator<WindowWithTitleButton> WindowList::FindTitle(const string& title_find)
{   
    return std::find_if(begin(), end(), MatchWindowTitle(title_find));
}
优化提示
  • 原代码中iter = begin(), iter = end()的赋值写法完全多余,直接将begin()、end()返回的迭代器作为参数传入find_if即可。
  • 字符串参数尽量用const string&传递,避免不必要的内存拷贝。
  • 字符串相等判断直接用==即可,不需要手动调用compare方法判断返回值是否为0,二者逻辑完全等价,前者可读性更好。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 16:31:37