Std :: map \ std :: set包含重复键

时间:2016-02-29 10:31:25

标签: c++ std stdmap stdset

我有一个问题,虽然我明白,这是一个愚蠢的问题,但我没有找到自己的解决方案。

所以,我试图积累一个具有我所拥有的结构的唯一值的容器。

struct Symbol {
    D2D1_RECT_F bbox;
    wchar_t data;
    fz_font_s* font;
    float color[4];
};

我正在做的是尝试使用std::mapstd::set。意识到,我需要提供一个谓词,以便为容器提供一种确定顺序的方法。我所拥有的是:

struct SymbolCmp {
    bool operator() (const Symbol& lhs, const Symbol& rhs) const
    {
        auto errorHandler = (lhs.bbox.top == rhs.bbox.top) ? (lhs.bbox.left < rhs.bbox.left) : lhs.bbox.top < rhs.bbox.top;

        if (lhs.data == rhs.data &&
            lhs.font != rhs.font) {
            return errorHandler;
        }

        float lArea = (lhs.bbox.bottom - lhs.bbox.top) *
            (lhs.bbox.right - lhs.bbox.left);
        float rArea = (rhs.bbox.bottom - rhs.bbox.top) *
            (rhs.bbox.right - rhs.bbox.left);

        auto relative = (lArea / rArea < 0.95f ||
            lArea / rArea > 1.05f);

        return (lhs.data == rhs.data) ? relative && errorHandler : (lhs.data < rhs.data);
    }
};

然后我尝试在std::set<Symbol, SymbolCmp>std::map<Symbol, byte, SymbolCmp>内插入值。

可悲的是,结果令人沮丧,因为我得到的东西离一个对象很远,只包含唯一的键。大多数符号都有重复。

所以我真的明白了,我错过了什么?

1 个答案:

答案 0 :(得分:1)

您的谓词不能确保严格的弱顺序。以下应该工作:

struct SymbolCmp {
    bool operator() (const Symbol& lhs, const Symbol& rhs) const
    {
        if(lhs.data == rhs.data) {
            return (lhs.bbox.top == rhs.bbox.top) ? (lhs.bbox.left < rhs.bbox.left) : lhs.bbox.top < rhs.bbox.top;
        } else {
            return lhs.data < rhs.data;
        }
    }
};

如果您想在逻辑中使用fontcolor和维度,请确保遵循strct-weak排序约束。