std :: set和boost :: shared_ptr唯一键识别问题

时间:2012-01-07 17:06:46

标签: c++ boost std smart-pointers

我在理解std::set(或std::map等)如何识别唯一键时遇到问题。我想要做的是在boost::shared_ptr中包装一个struct对象,然后将该共享指针存储在std::set容器中:

假设结构是一种颜色:

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;
};

上面的代码无法根据包装的shared_ptr结构唯一标识Color个对象。我一直认为std::set容器会对两个对象运行一个比较函数,如果它们都不大于或小于另一个 - 它会假设它们是相等的。请注意,我不能使用默认shared_ptr::operator<()less<...>,因为该实现基于指针地址。

我错过了什么?

P.S。我在shared_ptr内包装颜色,因为我需要在某个时刻知道它们的引用计数(并删除引用计数为1的颜色 - 即仅由std::set容器本身引用)。有没有更好的方法来获得相同的结果?

1 个答案:

答案 0 :(得分: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,因此您不会引入依赖于兼容的相等运算符,但在这个简单的浮点数情况下我们没问题。 / p>

顺便说一句,您不需要struct,您只需声明static bool ColorCompare(...);函数即可。另一个选择是直接在operator<中定义struct Color以使所有内容都自包含(因此您只需要一个通用的解除引用比较器(智能)指针)。