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

Set::find()存储对象指针时异常:插入顺序影响查找结果

std::set存储对象指针时find()失效的原因分析

问题描述

使用std::set存储对象指针,自定义仿函数ptr_compare通过对象内容比较,但set::find()在不同插入顺序下表现不一致:按a1、a2、a3插入时能找到a2,按a1、a3、a2插入时找不到a2。

相关代码如下:

比较仿函数

template<class T> struct ptr_compare
{
    bool operator()(const T* lhs, const T* rhs) const
    {
        return *lhs < *rhs;
    }
};

样本类A

class A {
  private:
    string str;
  public:
    A(string s)
    {
        str = s;
    }
    bool operator <(const A& obj) const
    {
        return this->str.compare(obj.get_str());
    }
    
    string get_str() const
    {
        return str;
    }
};

问题根源

问题不在指针比较的方式,而是类A的operator<违反了std::set要求的严格弱序规则。

std::string::compare()的返回值是int:

  • 小于0:当前字符串小于参数字符串
  • 等于0:两个字符串相等
  • 大于0:当前字符串大于参数字符串

但你直接把这个int返回给bool类型的operator<,会导致:

  • 当当前字符串大于参数字符串时,compare()返回正数,转换成bool是true,这就会让a < b和b < a同时为true,完全破坏了严格弱序的要求。

std::set依赖严格弱序维护内部平衡树结构,一旦比较规则失效,容器行为就变成未定义的——不同插入顺序触发不同的未定义行为,便出现了有时能找到、有时找不到的情况。

修复方案

修改类A的operator<,确保它正确实现严格弱序:

方案1:直接使用字符串的<运算符

bool operator <(const A& obj) const
{
    return this->str < obj.get_str();
}

方案2:正确判断compare()的返回值

bool operator <(const A& obj) const
{
    return this->str.compare(obj.get_str()) < 0;
}

修正后,std::set的内部结构能正确维护,无论插入顺序如何,find()都能正常工作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 23:42:47