c++ - 如何将 std::set_intersection 用于 2 个不同但相关的类型并输出到另一种类型

标签 c++ c++11 stl stl-algorithm

我需要用 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 进行转换和StructBStructC ,所以我们需要一个。添加一个最简单的方法是

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/

相关文章:

c++ - 如何正确推断模板的返回类型?

c++ - 如何将 std::bind 与 compose2 一起使用?

c++ - for_each 指针 vector 中的指针

c++ - 是否可以将默认构造函数设置为 `std::map<T1, T2>` 值?

CPU 寄存器中返回的用户定义类型的 C++ 对象。实例方法如何工作?

c++ - 引用计数类和多线程

c++ - 在成员函数内的 lambda 捕获列表中使用成员变量

c++ - 尝试使用 OpenGL 时出错

c++ - 什么链接到 MSVCRTD?

c++ - STL 堆栈和 priority_queue 的插入器