2016-02-29 92 views
2

我有一个问题,虽然我明白,这是一个愚蠢的问题要问,但我没有找到我自己的解决方案。Std :: map std :: set包含重复键

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

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>内插入值。

令人遗憾的是,结果令人沮丧,因为我得到的东西离对象很远,只包含唯一键。 Symbol的大部分都有重复。

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

+0

你是否用两个符号a和b检查了SymbolCmp(a,b)和SymbolCmp(b,a)的返回值? – Anedar

+0

没有仔细看,但在我看来'SymbolCmp'不满足[严格 - 弱排序](https://www.sgi.com/tech/stl/StrictWeakOrdering.html)。提示:如果'relative'总是'true',它还会发生吗? –

+0

需要严格的弱排序。你能保证用你写的所有代码吗?只是使用浮点本身来确定顺序是可疑的。 – PaulMcKenzie

回答

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弱顺序约束。

+0

你能解释一下,在我的谓词中严格无序的排序有什么问题?我的意思是,在什么情况下它将无法提供订单? –

+0

@AleksandrKurinnoi如果有三个类A,B和C,使得A.font = B.font,并且这些区域几乎相同,那么对于A