2012-01-07 50 views
0

我在理解std::set(或std::map等)如何標識唯一密鑰方面存在問題。我試圖做的事情是內boost::shared_ptr,然後商店std::set容器內共享指針換一個struct對象:std :: set和boost :: shared_ptr唯一密鑰標識問題

假設的結構是一個顏色:

struct Color { 
    float r; 
    float g; 
    float b; 
}; 

然後將容器和比較函數對象在另一個類定義:

class AnotherClass { 

    typedef boost::shared_ptr<Color> ColorPtr; 

    public: 

     struct ColorCompare { 
      bool operator()(const ColorPtr &a, const ColorPtr &b) const { 
       return (a->r > b->r) && (a->g > b->g) && (a->b > b->b); 
      } 
     }; 

    private: 

     // Container definition 
     std::set<ColorPtr, ColorCompare> colors; 
}; 

上面的代碼不能唯一地識別基於它們包裹Color結構shared_ptr對象。我一直認爲std::set容器會對兩個對象運行比較函數,如果它們中的任何一個都不大於或小於另一個 - 它會認爲它們是相等的。請注意,由於該實現基於指針地址,因此我不能使用默認的shared_ptr::operator<()less<...>

我錯過了什麼?

p.s.我在shared_ptr之內包裝顏色,因爲我需要知道它們在某個點的引用計數(並刪除參考計數爲1的顏色 - 也就是說,只能由std::set容器本身引用)。有沒有更好的方法來獲得相同的結果?

+0

您可以存儲'weak_ptr'並將它們移除(如果它們是'expired()')。 – Xeo 2012-01-07 17:27:25

+0

但是'weak_ptr'不是'shared_ptr'的觀察者嗎?所以我仍然需要在某個時刻存儲或放棄'shared_ptr'。感謝您的建議。 – Sim 2012-01-07 19:14:47

+0

'weak_ptr :: lock'創建一個新的'shared_ptr'。 – Xeo 2012-01-07 21:57:28

回答

4

該比較需要是一個嚴格的弱排序,你的不是。 (?例如,如何爲(1,0,0)和(0,1,0)排序)操作方式:

return (a->r > b->r)         || 
     ((a->r == b->r) && (a->g > b->g))    || 
     ((a->r == b->r) && (a->g == b->g) && (a->b > b->b)); 

這是元素的元組標準的字典順序。

請注意,您一般會編寫!(b->r > a->r)而不是a->r == b->r,這樣您就不會在兼容的相等運算符上引入依賴關係,儘管在這種簡單的浮點運算中我們很好。

順便說一下,你不需要一個struct,你可以簡單地聲明一個static bool ColorCompare(...);函數。另一種選擇是直接在struct Color中定義operator<以使所有內容都是獨立的(因此您只需要一個通用的(智能)指針的取消比較器)。

+0

'Color'中的'operator <'不能用於IIRC,因爲'shared_ptr'不會將比較轉發給實際的對象,而只是比較指針。此外,這再次表明嚴格 - 弱排序的正確實現可能是多麼醜陋。 [很高興我找到了解決方案!](http://stackoverflow.com/questions/6218812/implementing-comparision-operators-via-tuple-and-tie-a-good-idea) – Xeo 2012-01-07 17:19:06

+0

@Xeo:你還需要一個通用的「共享指針按值比較器」,但可以在不考慮指針對象內部的情況下完成。我加了一張紙條。順便說一句,好的鏈接。 – 2012-01-07 17:23:44

+0

這是問題 - 謝謝。我試過你的實現,但確實得到了一些奇怪的stl異常「invalid operator <」。然後我嘗試[這個答案](http://stackoverflow.com/a/979768/454230),嚴格的弱排序算法似乎很好。 – Sim 2012-01-07 19:11:57

相關問題