C ++ std :: set自定义比较器

时间:2013-05-02 12:00:33

标签: c++ comparator stdset

好吧,我的问题是我正在使用带有自定义比较器的std :: set,例如:

class A
{
public:
    A(int x, int y):
        _x(x), _y(y)
    {
    }

    int hashCode(){ return (_y << 16) | _x; }

private:
    short int _y;
    short int _x;
};

struct comp
{
    bool operator() (A* g1, A* g2) const
    {
        return g1->hashCode() < g2->hashCode();
    }
};

所以,我像

一样使用它
std::set<A*, comp> myset;

// Insert some data
A* a = new A(2,1);
A* b = new A(1,3);
myset.insert(a);
myset.insert(b);

现在我的问题是我想这样做:

myset.find( (2 << 16) | 1 );

但是,当然,它除了A *而不是短的。

所以,我知道我可以使用std :: find_if,但它不会使自定义比较器变得无用吗?它会迭代整个列表,不是吗?有没有什么方法可以使用hashCode而不是对象本身?

谢谢!

4 个答案:

答案 0 :(得分:3)

set::find接受key_type类型的参数(请参阅讨论Why is set::find not a template?)。使用std :: set,您必须构造一个临时对象以使用find

myset.find(A(2, 1));

如果构建A的成本不高,则可能需要使用std::map<int, A>(或其周围的包装)。

答案 1 :(得分:1)

您无法使用std::set执行此操作,因为std::set<>::find是 不是(成员)模板;参数必须是关键类型。 对于像你这样的简单类,很可能使用 std::vector<A>并保持排序(使用std::lower_bound 用于查找,并作为插入点)将同样快。 使用std::lower_bound,您可以传入比较器 使用您想要的任何类型作为关键。你所要做的就是确保这一点 你的comp类可以处理混合类型比较,例如:

struct Comp
{
    bool operator()( A const&, B const& ) const;
    bool operator()( A const&, int ) const;
    bool operator()( int, A const& ) const;
};

答案 2 :(得分:0)

myset.find(&A(2, 1));

或者

A a(2, 1);
myset.find(&a);

答案 3 :(得分:0)

您已定义std::set<A*, comp> myset;,因此std::find()必须采用A*参数。

std::set<A*, comp> myset;

// Insert some data
A* a = new A(2,1);
A* b = new A(1,3);
myset.insert(a);
myset.insert(b);

然后,你需要做

myset.find(&A(2,1))

回到你的问题,std::find()没有带你的自定义比较器。实际上,您需要使用std::find_if