C++ 无法在具有公共字段的不同类型的结构上应用std::set_交集

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

我试图使用来查找两种完全不同类型的数据结构之间的公共元素,这些数据结构具有公共绑定“name”字段

我看了以下内容,但这似乎迫使我在我试图避免的2种不同结构类型之间进行自定义转换(因为这些类型来自第三方)

下面的代码片段显示了我试图实现的目标

// 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 这导致以下详细错误输出。我希望避免定制结构(因为我尝试使用的实际结构来自第三方)来实现从StructA到StructB的转换器,反之亦然。有什么方法可以避免这种情况,只需使用一些简单的lambda就可以实现两个具有公共字段的相对简单的结构之间的简单绑定吗?
提前谢谢

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 {
    // ...
};