有没有办法在两种不同类型的集合上执行std :: set_intersection?
我有两套:
std::set<X1> l_set1;
std::set<X2> l_set2;
我可以为它们定义一些比较器来检查X1和X2是否相等。
struct sample_comparer
{
bool operator()(const &X1 p_left, const &X2 p_right)
{
return p_left == p_right;
}
};
现在,我尝试在这两组上进行集合交集:
std::set<X1> l_intersect;
std::set_intersection(l_set1.begin(), l_set1.end(), l_set2.begin(), l_set2.end(),
std::inserter(l_intersect, l_intersect.begin()), sample_comparer());
不幸的是,我无法强制使用此代码。我甚至不确定这是否可行,但是从set_intersection的description我知道我可以使用两个不同的迭代器。
我试图搜索一些我想要的代码示例,但没有找到任何代码示例?有人能为我提出一个有问题的工作代码示例吗?
更新: 错误是:
错误:stl_function.h:227:'operator&lt;'不匹配在'__x&lt; __y'
提前致谢!
答案 0 :(得分:4)
它不起作用,因为两个输入必须可分配给输出迭代器类型。您可以向X1,X2添加一些隐式转换运算符,它们在它们之间进行转换以使其正常工作。
答案 1 :(得分:3)
PlasmaHH的评论可能是个问题。
set_intersection等函数的工作方式是:a < b
然后b < a
因此,ample_comparer需要能够比较两种方式:
struct sample_comparer
{
bool operator()(const &X1 p_left, const &X2 p_right)
{
return p_left == p_right;
}
bool operator()(const &X2 p_left, const &X1 p_right)
{
return p_left == p_right;
}
};
以下实际上并没有做任何明智的事 - 但它确实编译得很干净:
struct A
{
struct Compare { bool operator () (A const &, A const &) { return false;} };
};
struct B
{
struct Compare { bool operator () (B const &, B const &) { return false; } };
};
typedef std::set<A, A::Compare> S1;
typedef std::set<B, B::Compare> S2;
class IntersectionCompare
{
public:
bool operator ()(S1::value_type, S2::value_type) { return false; }
bool operator ()(S2::value_type, S1::value_type) { return false; }
};
void bar (S1 & s1, S2 & s2)
{
S1 result;
std::set_intersection (s1.begin ()
, s1.end ()
, s2.begin ()
, s2.end ()
, std :: insert_iterator< S1 > (result, result.end ())
, IntersectionCompare ());
}
答案 2 :(得分:2)
我认为不可能,(至少没有用户定义的转换)。
来自documentation中的“类型要求”部分:InputIterator1 and InputIterator2 have the same value type.
答案 3 :(得分:0)
首先根据文档set_intersection使用运算符&lt;。 第二,你可以制作第三个结构,它将从你将用来比较的字段中提取
std::set<X1> l_set1;
std::set<X2> l_set2;
struct XCompare
{
int value;
XCompare(const X1& x)
{
value = x.value;
}
XCompare(const X2& x)
{
value = x.value;
}
}
std::set_intersection(...,...,[](const XCompare& c1, const XCompare& c2){
... } )
你可以沿着这条路走下去创建一个可以做任何事情的自定义包装器,除非你的两种类型可以比较
template<typename T1, typename T2>
struct ValueWrapper
{
T1 const* v1 = nullptr;
T2 const* v2 = nullptr;
ValueWrapper(const T1& value)
{
v1 = &value;
}
ValueWrapper(const T2& value)
{
v2 = &value;
}
bool operator<(const ValueWrapper& other)
{
if (v1 != nullptr)
{
if (other.v1 != nullptr)
{
return *v1 < *(other.v2)
}
... } }
template<typename T1, typename T2>
struct ValueWrapperComparator
{
bool operator()(ValueWrapper<T1,T2> v1, ValueWrapper<T1,T2> v2)
{
return v1 < v2;
}
}
这样的事情。我没有测试它并且它不会编译但是你明白了。也许类似的东西隐藏在STL库中某处类似的东西
编辑:顺便说一下,我认为你可以使用某种变体类型(boost :: variant或std :: variant)我认为它已经这样做了......