std::set 和 boost::shared_ptr 唯一键识别问题
我在理解 std::set
(或 std::map
等)如何识别唯一键时遇到问题。我想做的事情是将一个结构对象包装在 boost::shared_ptr
中,然后将该共享指针存储在 std::set
容器中:
假设该结构是一个color:
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<...>
因为该实现是基于指针地址的。
我缺少什么?
ps 我将颜色包装在 shared_ptr
中,因为我需要在某个时刻知道它们的引用计数(并删除引用计数为 1 的颜色 - 也就是说,仅由 std::set< 引用/code> 容器本身)。有没有更好的方法来获得相同的结果?
I am having issues understanding how std::set
(or std::map
etc) identify unique keys. The thing I am trying to do is wrap a struct object within boost::shared_ptr
and then store that shared pointer within std::set
container:
Let's say the struct is a color:
struct Color {
float r;
float g;
float b;
};
Then the container and comparison function object is defined in another class:
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;
};
The code above is failing to uniquely identify shared_ptr
objects based on their wrapped Color
struct. I always thought that the std::set
container would run a comparison function on two objects, and if none of them is greater than or less than the other - it will assume they are equal. Note, that I cannot use default shared_ptr::operator<()
and less<...>
as that implementation is based on pointer address.
What am I missing?
p.s. I am wrapping colors within shared_ptr
since I need to know their reference count at some point (and remove colors that are at ref count 1 - that is, only referenced by std::set
container itself). Is there a better way to get the same result?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
比较必须是严格的弱排序,而您的则不是。 (例如,(1,0,0) 和 (0,1,0) 是如何排序的?)这样做:
这是元素元组的标准字典顺序。
请注意,通常您会编写
!(b->r > a->r)
而不是a->r == b->r
这样您就不会引入对兼容的相等运算符的依赖,尽管在这种简单的浮点数情况下我们没问题。顺便说一句,您不需要
struct
,只需声明一个static bool ColorCompare(...);
函数即可。另一种选择是直接在struct Color
中定义一个operator<
以使所有内容都是独立的(因此您只需要一个用于(智能)指针的通用解引用比较器)。The comparison needs to be a strict weak ordering, which yours isn't. (For example, how are (1,0,0) and (0,1,0) ordered?) Do this:
This is the standard lexicographic ordering on a tuple of elements.
Note that you would write
!(b->r > a->r)
instead ofa->r == b->r
in general so that you don't introduce a dependence on a compatible equality operator, though in this simple case of floats we're fine.By the way, you don't need a
struct
, you can simply declare astatic bool ColorCompare(...);
function. Another option is to define anoperator<
directly in thestruct Color
to make everything self-contained (so you'll just need a generic dereferencing-comparator for (smart) pointers).