0

好吧,我的问题是我正在使用带有自定义比较器的 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* 而不是 short int。

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

谢谢!

4

4 回答 4

2

set::find接受类型参数key_type(参见讨论为什么 set::find 不是模板?)。使用 std::set 你必须构造一个临时对象来使用find

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

如果 A 构造起来并不便宜,您可能想要使用 a std::map<int, A>(或围绕它的包装器)。

于 2013-05-02T12:04:15.453 回答
1

您不能使用 来执行此操作std::set,因为std::set<>::find它不是(成员)模板;参数必须是键类型。对于像您这样的简单类,使用 an 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;
};
于 2013-05-02T12:11:04.603 回答
0

你已经定义了 a 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.

于 2013-05-02T15:46:05.933 回答
0
myset.find(&A(2, 1));

或者

A a(2, 1);
myset.find(&a);
于 2013-05-02T12:11:08.010 回答