我需要用 std::set_intersection 做一些有点奇怪的事情,但我不太明白。大约一个月前,我问了一个类似的 question ,由于对这个问题的出色回答,我解决了使用两个 vector 之间的公共(public)链接字段使 std::set_intersection 工作的问题,每个 vector 包含不同类型的对象。
我现在面临的问题是我试图让下面的代码工作,我基本上需要将 std::set_intersection 的输出写入一个新类型,该类型实际上是 StructA 中的一些字段和其他字段之间的 union 来自结构B。我使用了用户 tclamb 编写的稍微修改过的示例,但它无法编译,并且我在编译器错误中有点迷失。我很确定我面临的一些问题与限制有关
根据std::set_intersection中类型的要求部分,InputIterator1和InputIterator2具有相同的值类型。就我而言,情况并非如此,在 tclamb 的解决方案中也并非如此,但它似乎有效。
我刚刚编辑了下面的代码,并纳入了 @ivar 对一些冗余代码的建议 - 这使得问题更容易阅读 - 它现在正在编译和运行 - 但仍然产生不完全是我想要的结果。实时代码也发布在 coliru
#include<vector>
#include<algorithm>
#include<string>
#include <iostream>
#include <iterator>
// I wish to return a vector of these as the result
struct StructC {
std::string mCommonField;
std::string mNameFromA; // cherry picked from StructA
std::string mNameFromB; // cherry picked from StructB
float mFloatFromA; // cherry picked from StructA
int mIntFromB; // cherry picked from StructB
};
struct StructA {
// conversion operator from StructA to StructC
operator StructC() { return { mCommonField, mNameAString, "[]", mFloatValueA, 0 }; }
std::string mCommonField;
std::string mNameAString;
float mFloatValueA;
};
struct StructB {
// conversion operator from StructB to StructC
operator StructC() { return { mCommonField, "[]", mNameBString, 0.0f, mIntValueB }; }
std::string mCommonField;
std::string mNameBString;
int mIntValueB;
};
// Comparator thanks to @ivar
struct Comparator {
template<typename A, typename B>
bool operator()(const A& a, const B& b) const {
return a.mCommonField < b.mCommonField;
}
};
template<typename CharT, typename Traits>
std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>& os, StructC const& sc) {
return os << sc.mCommonField << " - " << sc.mNameFromA << " - "
<< sc.mNameFromB << " - " << std::fixed << sc.mFloatFromA << " - " << sc.mIntFromB << std::endl;
}
int main() {
Comparator comparator;
// initially unsorted list of StructA
std::vector<StructA> aStructs = {
{"hello", "nameA1", 1.0f},
{"goodbye", "nameA2", 2.0f},
{"foo", "nameA3", 3.0f}
};
// initially unsorted list of StructB
std::vector<StructB> bStructs = {
{"hello", "nameB1", 10}, // <-- intersection as mCommonField("hello") also in aStructs
{"goodbye", "nameB2", 20}, // <-- intersection as mCommonField("goodbye") also in aStructs
{"bar", "nameB3", 30}
};
// in the above list, "hello" & "goodbye" are the common in both aStructs & bStructs
// pre-sort both sets before calling std::intersection
std::sort(aStructs.begin(), aStructs.end(), comparator);
std::sort(bStructs.begin(), bStructs.end(), comparator);
std::vector<StructC> intersection;
std::set_intersection(aStructs.begin(), aStructs.end(),
bStructs.begin(), bStructs.end(),
std::back_inserter(intersection),
comparator);
std::copy(intersection.begin(), intersection.end(),
std::ostream_iterator<StructC>(std::cout, ""));
return 0;
}
最佳答案
有两个错误。第一,back_inserter
创建 back_insert_iterator<vector<StructC>>
,其中有 operator=
上vector<StructC>::value_type
,即StructC
。没有从 StructA
进行转换和StructB
至StructC
,所以我们需要一个。添加一个最简单的方法是
struct StructA {
// ...
operator StructC() { return {mCommonField, int(mFloatValue), 0}; }
};
等等。其次,没有operator <<
对于 StructC
。修复这些错误我们有 fully functional solution .
UPD。您可以将结果放入 vector<Common>
,看起来很像是为这个问题设计的。
关于c++ - 如何将 std::set_intersection 用于 2 个不同但相关的类型并输出到另一种类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23158127/