Ну, моя проблема в том, что я использую 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 вместо самого объекта?
Спасибо!
set::find
принимает аргумент типа key_type
(см. обсуждение Почему set :: find не шаблон?). Используя std :: set, вы должны создать временный объект для использования find
,
myset.find(A(2, 1));
Если А не дешево построить, вы можете использовать std::map<int, A>
(или обертка вокруг этого) вместо этого.
Вы не можете сделать это с 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;
};
myset.find(&A(2, 1));
Или же
A a(2, 1);
myset.find(&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
,