set_intersection使用自定义设置比较器



当我将 std::set_intersection 函数与具有自定义比较器的集合一起使用时,我没有得到预期的结果。 以下代码输出 {5,9,7} 相交{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将对 set 元素使用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。

您正在混合传递给std::setstd::set_intersection的比较函数。当传递给std::set时,Compare函数用于排序,因为它是键比较函数。当传递给std::set_intersection时,它用于定义交集。

请尝试以下操作:

#include <iostream>
#include <cstdlib>
#include <set>
#include <algorithm>
struct cmp {
bool operator()(int *a, int *b) const {
return *a < *b;
}
};
using stupid_set = std::set<int*, 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) {
std::cout << "s0:" << *s << std::endl;
}
for (auto s:s1) {
std::cout << "s1:" << *s << std::endl;
}
std::set_intersection(
s0.begin(),
s0.end(),
s1.begin(),
s1.end(),
std::inserter(i, i.begin()),
cmp()
);
for (auto x : i) {
std::cout << "Int=" << *x << std::endl;
}
}

查看直播

最新更新