find_if error: invalid initialisation of reference of type 'const node&' from expression of type 'node*'

find_if error: invalid initialisation of reference of type 'const node&' from expression of type 'node*'

我有一个结构节点:

struct node {
    node *parent;
    int x, y;
    float f, g, h;
    };

我定义了一个谓词条件 bool 函数,用于查找结构成员是否已经存在于向量中。

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);

报错: 从 'node*' 类型的表达式对 'const node&' 类型的引用进行无效初始化。有人可以向我解释错误吗?

这是 cppreference.comfind_if 的可能实现:

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;
}

看起来你有一个 node*vector,因此,当你迭代和取消引用迭代器时,你传递给 p 的是一个 node* 但是不是 node& 元素。您可以更改函数以接受指针来解决此问题。另外,请参阅 find_if 实现接受 UnaryPredicate p,因此您不能将接受两个参数的函数传递给它。

编辑:

解决此问题的另一种C++11方法是使用functionalheader中的bind并将ref绑定到Isinit作为:

using namespace std::placeholders;
auto referIt = find_if (open.begin(), open.end(), std::bind(Isinit, _1, &ref));

您的代码有两个问题:参数数量和参数类型:

vector<node*>::iterator referIt = 
    find_if (open.begin(), open.end(), Isinit);

bool Isinit(const node &nm, const node &ref);

find_if 采用 一元 谓词。它将在每个元素上调用它,直到找到谓词 returns 为真的元素。该谓词必须接受容器中类型的 one 参数。根据您对 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 lambda,都可以在线完成:

auto referIt = find_if(open.begin(), open.end(), [ref](const node* nm){
    return nm->x == ref->x && nm->y == ref->y;
});