используя std :: find с предикатом

Я хочу использовать std::find функция вместе с предикатом (не уверен, что я использую правильное слово). Вот код

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class foo {
public:
typedef pair< int, vector<int> > way;
typedef pair< int, int > index;
typedef pair< index, vector<way> > entry;
vector< entry > table;

void bar()
{
vector<int> v1;
v1.push_back(1);
v1.push_back(2);

way w = make_pair( 1, v1 );
vector<way> v2;
v2.push_back(w);

index id = make_pair( 10, 20 );
entry en = make_pair( id, v2 );
table.push_back( en );
}
void insert()
{
index new_id = make_pair( 10, 20 );
if ( find(table.begin(), table.end(), new_id) != table.end() ) {
// index matched in the table
// then I will push back a new pair (way)
// to the second part of the entry
}
}
};
int main()
{
foo f;
f.bar();
f.insert();
return 0;
}

Как вы видете, find() должен искать table на основе первого элемента в каждой записи. Сейчас говорится, что == не перегружен для сравнения pair,

9

Решение

Ты хочешь std::find_if:

...
if(find_if(table.begin(), table.end(), [&new_id](const entry &arg) {
return arg.first == new_id; }) != ...)

РЕДАКТИРОВАТЬ: Если у вас нет C ++ 11 (и, следовательно, нет лямбда-выражений), вам нужно создать пользовательский функтор (функцию или объект-функцию) для сравнения entry::first с разыскиваемым index:

struct index_equal : std::unary_function<entry,bool>
{
index_equal(const index &idx) : idx_(idx) {}
bool operator()(const entry &arg) const { return arg.first == idx_; }
const index &idx_;
};

...
if(find_if(table.begin(), table.end(), index_equal(new_id)) != ...)

РЕДАКТИРОВАТЬ: С index это просто пара ints, вы также можете просто захватить его по значению, а не по константной ссылке, чтобы сделать код более четким и кратким, но на самом деле это тоже не имеет значения.

21

Другие решения

В C ++ 11 вы также можете использовать std::any_of

if (std::any_of(table.cbegin(), table.cend(),
[&new_id](const entry &arg) { return arg.first == new_id; }))
3

По вопросам рекламы [email protected]