使用自定义比较器的std::set_intersection语法及报错问题
解决std::set_intersection自定义比较器的const限定符错误
嘿,我来帮你搞定这个问题!你遇到的那个passing ‘const Foo’ as ‘this’ argument discards qualifiers错误,核心原因其实很简单——你的自定义比较器的operator()没有被标记为const成员函数,而STL容器和算法(比如std::set和std::set_intersection)要求比较器的调用必须是const-safe的。
第一步:先修复比较器的两个小问题
先看你给出的代码片段,你的Compare_custom有两个明显的问题:
struct Compare_custom { bool operator () (const Foo & lhs, const Foo & rhs) { return (lhs.str.size() > rhs.str.size(...); // 这里括号没闭合,语法错误 } };
- 缺少const修饰:
operator()必须声明为const,因为STL算法会用const上下文调用它,确保比较器不会修改自身状态 - 语法错误:
rhs.str.size(...的括号没写完,应该是rhs.str.size()
修复后的比较器应该是这样:
struct Compare_custom { bool operator () (const Foo & lhs, const Foo & rhs) const { // 加上const关键字 return lhs.str.size() > rhs.str.size(); // 修正括号问题 } };
第二步:确保集合用对了比较器
你在定义std::set的时候,一定要把Compare_custom作为模板参数传进去,不然std::set会默认用std::less<Foo>,后续调用set_intersection时会因为排序规则不匹配出问题。比如:
// 定义两个用自定义比较器排序的set std::set<Foo, Compare_custom> one; std::set<Foo, Compare_custom> two;
第三步:正确调用std::set_intersection
调用set_intersection时,要保证两个输入集合的排序规则一致(都是按字符串长度降序),同时输出容器也要匹配这个规则。用插入迭代器的写法如下:
std::set<Foo, Compare_custom> intersect; std::set_intersection( one.begin(), one.end(), two.begin(), two.end(), std::inserter(intersect, intersect.begin()), Compare_custom() // 显式传入比较器,或者依赖set的默认比较器 );
为啥会触发这个错误?
简单来说:当std::set_intersection处理const的Foo元素时,它会调用比较器的operator()。如果这个函数没加const,编译器会认为它可能修改比较器对象本身(哪怕你的代码里没这么做),但此时传递给函数的this指针是const的——相当于你试图用非const的方法去操作一个const对象,编译器当然会报错啦。
验证预期结果
假设你给one和two分别初始化了这些元素:
one包含str长度为5的f1、长度为3的f2two包含str长度为3的f2、长度为2的f3
修复后的代码运行后,intersect集合里就只会有f2,完全符合你的预期。
内容的提问来源于stack exchange,提问作者Elliott
相关产品推荐
相关产品推荐

