C++ 无法在具有公共字段的不同类型的结构上应用std::set_交集
我试图使用来查找两种完全不同类型的数据结构之间的公共元素,这些数据结构具有公共绑定“name”字段 我看了以下内容,但这似乎迫使我在我试图避免的2种不同结构类型之间进行自定义转换(因为这些类型来自第三方) 下面的代码片段显示了我试图实现的目标C++ 无法在具有公共字段的不同类型的结构上应用std::set_交集,c++,c++11,lambda,stl,set-intersection,C++,C++11,Lambda,Stl,Set Intersection,我试图使用来查找两种完全不同类型的数据结构之间的公共元素,这些数据结构具有公共绑定“name”字段 我看了以下内容,但这似乎迫使我在我试图避免的2种不同结构类型之间进行自定义转换(因为这些类型来自第三方) 下面的代码片段显示了我试图实现的目标 // common field used for set intersection typedef struct StructA { std::string mCommonField; float mFloatValue; } Struct
// common field used for set intersection
typedef struct StructA {
std::string mCommonField;
float mFloatValue;
} StructA;
typedef struct StructB {
std::string mCommonField;
int mValue1;
short mValue2;
} StructB;
// initially unsorted list
std::vector<StructA> aStructs = {{"hello", 1.0f}, {"goodbye", 2.0f}, {"foo", 3.0f}};
// initially unsorted list
std::vector<StructB> bStructs = {{"hello", 1, 2}, {"goodbye", 3, 4}, {"bar", 5, 6}};
// sorting both sets before calling std::intersection
std::sort(aStructs.begin(), aStructs.end(),
[](const StructA& lhs, const StructA& rhs) {
return lhs.mCommonField < rhs.mCommonField;
});
std::sort(bStructs.begin(), bStructs.end(),
[](const StructB& lhs, const StructB& rhs) {
return lhs.mCommonField < rhs.mCommonField;
});
std::vector<StructA> intersection;
std::set_intersection(
aStructs.begin(), aStructs.end(),
bStructs.begin(), bStructs.end(),
std::back_inserter(intersection),
[](const StructA& lhs, const StructB& rhs){
return lhs.mCommonField < rhs.mCommonField;
});
//用于集合交点的公共字段
类型定义结构{
std::字符串mCommonField;
浮动mFloatValue;
}结构;
类型定义结构{
std::字符串mCommonField;
int mValue1;
短mv2;
}结构b;
//最初未排序的列表
向量结构={{“你好”,1.0f},{“再见”,2.0f},{“foo”,3.0f};
//最初未排序的列表
向量B结构={{“你好”,1,2},{“再见”,3,4},{“棒”,5,6};
//在调用std::intersection之前对两个集合进行排序
std::sort(aStructs.begin()、aStructs.end(),
[](常量结构A和lhs、常量结构A和rhs){
返回lhs.mCommonField
我正在使用Visual Studio 2013编译上述代码,但是上面的代码会抛出大量错误,如下所示。通读我在整理兼容的StrictWeakOrdering comp最后一个参数时遇到问题。理想情况下,我希望将其作为一次性lambda实现
template <class InputIterator1, class InputIterator2, class OutputIterator,
class StrictWeakOrdering>
OutputIterator set_intersection(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2,
OutputIterator result,
StrictWeakOrdering comp);
模板
输出迭代器集合\u交叉点(输入迭代器1第一个1,输入迭代器1最后一个1,
输入计数器2优先2,输入计数器2最后2,
输出结果,
严格的管理;
1> C:\ProgramFiles(x86)\Microsoft Visual Studio
12.0\VC\include\algorithm(3591):错误C2664:“bool(\uu vectorcall*)(const main::StructA&,const main::StructB&)”:无法将参数1从“main::StructB”转换为“const main::StructA&”1>原因:无法从“main::StructB”转换为“const main::StructA” 1> 没有可用的用户定义的转换运算符可以 执行此转换,否则无法调用运算符1>
C:\ProgramFiles(x86)\Microsoft Visual Studio 12.0\VC\include\algorithm(3625):请参阅函数模板实例化的参考 std::_Set_intersection(_InIt1,_InIt1,_InIt2,_InIt2,_OutIt,_Pr)' 正在用1>[1>
_OutIt=std::back\u insert\u迭代器>> 1> ,_InIt1=main::StructA*1>,
_InIt2=main::StructB*1>,\u Pr=main::1>]1>C:\Program Files(x86)\Microsoft Visual Studio 12.0\VC\include\algorithm(3654):请参阅函数模板实例化“\u OutIt”的参考 std::_Set_intersection2(_InIt1,_InIt1,_InIt2,_InIt2,_OutIt,_Pr,std::true_type)' 正在用1>[1>
_OutIt=std::back\u insert\u迭代器>> 1> ,_Pr=main:: 1> ,_InIt1=main::StructA*1>,
_InIt2=main::StructB*1>]1>…\src\dlf\main.cpp(111):请参阅对函数模板的引用 实例化“\u OutIt” std::set_intersection>>,std:_Vector_iterator>>,std::back_insert_iterator>>,main::>(_InIt1,_InIt1,_InIt2,_InIt2,_OutIt,_Pr)' 正在用1>[1>
_OutIt=std::back\u insert\u迭代器>> 1> ,_Ty=main::StructA 1>,
_InIt1=std::_Vector_iterator>> 1> ,
_InIt2=std::_Vector_iterator>> 1> ,_Pr=main:: 1> ] 我还尝试使用自定义comparator结构进行比较,但错误更令人困惑,如下所示:
struct comparator {
bool operator()(const StructA& lhs, const StructB& rhs) const {
return lhs.mCommonField < rhs.mCommonField;
}
bool operator()(const StructB& lhs, const StructA& rhs) const {
return lhs.mCommonField < rhs.mCommonField;
}
};
std::vector<StructA> intersection;
std::set_intersection(
aStructs.begin(), aStructs.end(),
bStructs.begin(), bStructs.end(),
std::back_inserter(intersection),
comparator());
结构比较器{
布尔运算符()(常量结构A和lhs、常量结构B和rhs)常量{
返回lhs.mCommonField提前谢谢 1> C:\ProgramFiles(x86)\Microsoft Visual Studio 12.0\VC\include\xutility(521):错误C2664:'bool main::comparator::operator()(const main::StructA&,const main::StructB&)const':无法从转换参数1 'main::StructA'到'const main::StructB&'1>原因:无法 从“main::StructA”转换为“const main::StructB”1>否 可执行此操作的用户定义的转换运算符 转换,或者无法调用运算符1>C:\Program 文件(x86)\Microsoft Visual Studio 12.0\VC\include\xutility(625): 参见函数模板实例化“bool”的参考 std::_Debug_lt_pred(_Pr,_Ty1,_Ty2,std:_Dbfile,std:_Dbline_t)' 正在用1>[1>
_Pr=main::comparator 1>,_Ty1=main::StructA&1>,_Ty2=main::StructA&1>]1>C:\Program Files(x86)\Microsoft Visual Studio 12.0\VC\include\xu
auto ta = aStructs.begin();
auto tb = bStructs.begin();
while( ta != aStructs.end() && tb != bStructs.end() ){
if( ta->mCommonField < tb->mCommonField ){
++ta;
} else if( tb->mCommonField < ta->mCommonField ){
++tb;
} else {
std::cout << "found common: " << ta->mCommonField << std::endl;
++ta;
++tb;
}
}
struct Common {
std::string const& mCommonField;
Common(StructA const& sa) : mCommonField{sa.mCommonField} {};
Common(StructB const& sb) : mCommonField{sb.mCommonField} {};
};
auto cmp = [](Common const& lhs, Common const& rhs) {
return lhs.mCommonField < rhs.mCommonField;
};
std::sort(aStructs.begin(), aStructs.end(), cmp);
std::sort(bStructs.begin(), bStructs.end(), cmp);
// ...
std::set_intersection(aStructs.begin(), aStructs.end(),
bStructs.begin(), bStructs.end(),
std::back_inserter(intersection),
cmp
);
struct comparator
{
template<typename T, typename U>
bool operator()(T const& lhs, U const& rhs) const {
return lhs.mCommonField < rhs.mCommonField;
}
};
std::sort(aStructs.begin(), aStructs.end(), comparator{});
std::sort(bStructs.begin(), bStructs.end(), comparator{});
// ...
std::set_intersection(aStructs.begin(), aStructs.end(),
bStructs.begin(), bStructs.end(),
std::back_inserter(intersection),
comparator{}
);
auto cmp = [](auto lhs, auto rhs) { return lhs.mCommonField < rhs.mCommonField; };
// ...
std::sort(aStructs.begin(), aStructs.end(), cmp);
std::sort(bStructs.begin(), bStructs.end(), cmp);
// ...
std::set_intersection(aStructs.begin(), aStructs.end(),
bStructs.begin(), bStructs.end(),
std::back_inserter(intersection),
cmp);
typedef struct Foo {
// ...
} Foo;
struct Foo {
// ...
};