Как использовать алгоритм поиска с вектором указателей на объекты в С++?
Я хочу найти в векторе указателей объектов для соответствующего объекта. Здесь пример кода для иллюстрации моей проблемы:
class A {
public:
A(string a):_a(a) {}
bool operator==(const A& p) {
return p._a == _a;
}
private:
string _a;
};
vector<A*> va;
va.push_back(new A("one"));
va.push_back(new A("two"));
va.push_back(new A("three"));
find(va.begin(), va.end(), new A("two"));
Я хочу найти второй элемент, введенный в вектор. Но так как вектор определяется как набор указателей, С++ не использует мой перегруженный оператор, но использует неявное сравнение указателей. Каков предпочтительный С++-путь решения в этой ситуации?
Ответы
Ответ 1
Используйте find_if с функтором:
template <typename T>
struct pointer_values_equal
{
const T* to_find;
bool operator()(const T* other) const
{
return *to_find == *other;
}
};
// usage:
void test(const vector<A*>& va)
{
A* to_find = new A("two");
pointer_values_equal<A> eq = { to_find };
find_if(va.begin(), va.end(), eq);
// don't forget to delete A!
}
Примечание: ваш оператор == для A должен быть const, или, что еще лучше, записать его как функцию члена, не являющегося членом.
Ответ 2
Либо используйте std:: find_if и предоставьте подходящий предикат, посмотрите другие ответы для примера.
Или в качестве альтернативы посмотрите boost:: ptr_vector, который обеспечивает прозрачный ссылочный доступ к элементам, которые действительно хранятся как указатели ( как дополнительный бонус, управление памятью также обрабатывается для вас)
Ответ 3
Попробуйте вместо этого использовать find_if. Он имеет параметр для предиката, где вы можете точно определить, как проверить, что вы нашли правильный элемент.
http://www.sgi.com/tech/stl/find_if.html
Ответ 4
Вы также можете использовать Boost:: Lambda:
using namespace boost::lambda;
find_if(va.begin(), va.end(), *_1 == A("two"));
Конечно, вы должны использовать shared_ptrs, поэтому вам не нужно забывать удалять!