的std ::设置。自定义套装

时间:2016-07-23 11:35:46

标签: c++ compare functor stdset equivalence

字。

我有一个结构,包含一个我希望用于比较和等效的字段,以及其他字段作为元数据:

struct read_tag{
    unsigned int read_id; // want std::set to use this
    int offset;           // metadata
    bool orientation;     // metadata
};

我有一个仿函数来完成这项工作:

struct read_tag_compare {
    bool operator() (const read_tag &a, const read_tag &b) const {
        return a.read_id > b.read_id
    }
};

和decl。所需的设置为

std::set<read_tag, read_tag_compare> block;

到目前为止所做的一切都在编译。问题如下:

如何制作包含std::set<read_tag, read_tag_compare>的集合。我想要这样的东西:

std::set< std::set<read_tag, read_tag_compare> > blocks;
blocks.insert(a_block); // comp error

但这给了我一个非常大的,难以破译的错误。

我认为它会以递归方式检查内部集合的比较方式并将其扩展到外部集合。所有人必须做的是为最内部的集合定义比较器。

例如

std::set<std:set<unsigned int>> set_o_sets;

工作正常,我无需定义如何比较std::set<unsigned int>

任何帮助都非常感激:D

2 个答案:

答案 0 :(得分:3)

< - std::set上的比较使用std::lexicographical_compare而不使用比较器,即它只是转发到元素类型的<。 (这是标准库的限制,因为这是为所有容器定义的,而不仅仅是有序关联的容器。)所以你需要的是一组自定义比较器,用于使用正确的字典比较重载的集合:

using read_tag_set = std::set<read_tag, read_tag_compare>;

struct read_tag_set_compare {
    bool operator()(const read_tag_set &a, const read_tag_set &b) const noexcept {
        return std::lexicographical_compare(a.begin(), a.end(),
                                            b.begin(), b.end(), a.key_comp());
        //                                                      ^^^^^^^^^^^^
    }
};

现在使用:std::set<read_tag_set, read_tag_set_compare>

代码显示为什么对于有序的关联容器没有明显的“修复”会使这个“正常工作”:如果容器使用自定义的有状态谓词,那么它通常不能保证两个成员实际上,不同的容器可以相互比较。你所知道的是,一个容器中的元素与该容器的比较器相当。因此,当您使用自定义比较器时,最好还明确说明两个不同的容器是如何关联的,并且明确断言比较两个容器是有意义的。

答案 1 :(得分:0)

我的g ++编译没有错误 - 5.3.1 ubuntu ..

#include<set>
#include<iostream>
using namespace std;

struct read_tag{
    unsigned int read_id; // want std::set to use this
    int offset;           // metadata
    bool orientation;     // metadata
};
struct read_tag_compare {
    bool operator() (const read_tag &a, const read_tag &b) const {
        return a.read_id > b.read_id;
    }
};
struct read_compare {
bool operator() (const set<read_tag, read_tag_compare> &a, const     set<read_tag, read_tag_compare> &b) const {
    return true;
}
};

int main()
{
    set<read_tag, read_tag_compare> block;
    set<set<read_tag, read_tag_compare>, read_compare> blocks;
    blocks.insert(block)
}

以上是我编译的内容。