Ошибка find_if: неверная инициализация ссылки типа 'const node&' из выражения типа 'node*'
У меня есть узел структуры:
struct node {
node *parent;
int x, y;
float f, g, h;
};
Я определяю функцию bool условия предиката следующим образом, чтобы найти, существует ли элемент struct в векторе или нет.
bool Isinit(const node &nm, const node &ref)
{
if(nm.x==ref.x && nm.y==ref.y)
return true;
else
return false;
}
Тогда я называю функцию следующим образом:
vector<node*>::iterator referIt=find_if (open.begin(), open.end(), Isinit);
Сообщается об ошибке: неверная инициализация ссылки типа 'const node&' из выражения типа 'node*'. Может кто-нибудь объяснить мне ошибку?
2 ответа
С вашим кодом есть две проблемы: количество аргументов и тип аргумента:
vector<node*>::iterator referIt =
find_if (open.begin(), open.end(), Isinit);
bool Isinit(const node &nm, const node &ref);
find_if
принимает унарный предикат. Он будет вызывать его для каждого элемента, пока не найдет элемент, для которого предикат возвращает true. Этот предикат должен принимать один аргумент типа, который находится в контейнере. От вашего звонка до find_if
этот тип node*
, Таким образом, ваша подпись должна быть:
bool Isinit(const node* nm);
Теперь это, вероятно, не будет удовлетворять то, что вы хотите сделать, так как вы ищете node*
соответствовать вашему ref
для этого вам нужно написать функтор:
struct Isinit {
const node* ref;
Isinit(const node*);
bool operator()(const node* nm); // compare passed-in 'nm'
// against member 'ref'
};
И призываем так:
vector<node*>::iterator referIt =
find_if (open.begin(), open.end(), Isinit(ref));
Которые, с лямбдами C++11, все могут быть сделаны в строке:
auto referIt = find_if(open.begin(), open.end(), [ref](const node* nm){
return nm->x == ref->x && nm->y == ref->y;
});
Вот возможная реализация find_if
с cppreference.com:
template<class InputIt, class UnaryPredicate>
InputIt find_if(InputIt first, InputIt last, UnaryPredicate p)
{
for (; first != last; ++first) {
if (p(*first)) {
return first;
}
}
return last;
}
Кажется, у вас есть vector
из node*
Таким образом, когда вы перебираете и разыменовываете итераторы, то, что вы передаете p
это node*
но не node&
элемент. Вы можете изменить свою функцию, чтобы принимать указатели, чтобы решить эту проблему. Кроме того, посмотрите, что find_if
реализация принимает UnaryPredicate p
таким образом, вы не можете передать ему функцию, принимающую два аргумента.
Редактировать:
Другая C++11
способ решить эту проблему заключается в использовании bind
от functional
заголовок и связать ref
в Isinit
как:
using namespace std::placeholders;
auto referIt = find_if (open.begin(), open.end(), std::bind(Isinit, _1, &ref));