c++ - 带有自定义设置比较器的 set_intersection
问题描述
当我将 std::set_intersection 函数与具有自定义比较器的集合一起使用时,我没有得到预期的结果。以下代码输出 {5,9,7} intersect {9} 为空集。但是,如果我只使用普通比较器,我会得到 {9}。
#include <iostream>
#include <cstdlib>
#include <set>
using namespace std;
auto cmp = [](int* a, int* b) { return a < b; };
using stupid_set = set<int*, decltype(cmp)>;
int main() {
int* n5 = new int(5);
int* n9 = new int(9);
int* n7 = new int(7);
stupid_set s0 {n5, n9, n7};
stupid_set s1 {n9};
stupid_set i;
for (auto s:s0) {
cout << "s0:" << *s << endl;
}
for (auto s:s1) {
cout << "s1:" << *s << endl;
}
set_intersection(s0.begin(), s0.end(), s1.begin(), s1.end(), std::inserter(i, i.begin()));
for (auto x : i) {
cout << "Int=" << *x << endl;
}
}
解决方案
您的代码存在多个问题,但核心问题是您将自定义比较器用于集合,而不是用于std::set_intersection
函数调用。此函数还需要比较元素,当然,必须将它们与相同的比较器进行比较。
利用:
struct cmp
{
bool operator()(int* a, int* b) const { return *a < *b; };
};
using stupid_set = set<int*, cmp>;
和
set_intersection(
s0.begin(), s0.end(),
s1.begin(), s1.end(),
std::inserter(i, i.begin()),
cmp{} // custom comparator used for sets
);
整个现场演示在这里:https ://godbolt.org/z/OAr3xV 。
请注意,如果您省略比较器,std::set_intersection
将operator<
用于设置元素,并且此操作对于指针通常是未定义的。
如果您真的想比较指针而不是那里指向的整数值,则需要使用std::less
,因为这甚至定义了一般指针的顺序:
struct cmp
{
bool operator()(int* a, int* b) const { return std::less<int*>{}(a, b); };
};
同样,您还需要将此比较器传递给std::set_intersection
。
现场演示:https ://godbolt.org/z/tLdfqn 。
推荐阅读
- mysql - 1and1 IONOS 数据库与 Node.JS
- c# - Unity Editor 在点击播放时冻结几秒钟 - Firebase.Editor 错误
- qt - 如何在 qml 中设计标尺
- outlook-redemption - 通过 RDOmessage.saveas 将 Msg 转换为 Eml 显示韩文的文本损坏
- vb.net - 文本框格式化字符串空格错误
- javascript - 无法使用 Ionic 和 Vue.js 保存文件
- r - 如何从 SuperLearner 模型中确定置换变量的重要性?
- google-chrome - 浏览器如何处理 OAuth2 中的 redirect_uri?
- c# - 如何将 json 转换为对象,如 CQRS 设计模式
- javascript - Recaptcha 验证后页面未重定向