find_if错误:类型' const节点&'的引用无效初始化来自类型'节点*'的表达

时间:2015-01-26 19:39:28

标签: c++ algorithm vector function-pointers

我有一个struct 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);

报告错误: 类型&#39; const节点&amp;&#39;的引用无效初始化来自类型&#39;节点*&#39;的表达式。有人可以向我解释错误吗?

2 个答案:

答案 0 :(得分: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 lambdas,可以全部在线完成:

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

答案 1 :(得分:0)

以下是来自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;
}

好像你有一个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));

{{1}}