繁体   English   中英

在stl make_heap C ++中将function_pointer作为比较器传递

[英]Passing a function_pointer as a comparator in a stl make_heap c++

我正在开发此程序以通过堆实现运行Dijkstra的算法,并且我希望它具有尽可能多的用途,因此我在使用函数指针以避免代码重复。 这是它弹出的错误。 我正在使用stl make_heap

"Type must use '.*' or '->*' to call pointer-to-member function in '__comp (...)', e.g. '(... ->* __comp) (...)' "heap.h     C/C++ Problem

这是Dijkstra的算法:

void Graph::dijkstraAlg(Vertex* ini, Vertex* fin, void(Graph::*weight_filler)(void), bool(Graph::*pq_order)(const Vertex* &, const Vertex* &)){

for(unsigned int i = 0; i < vertexs.size(); i++) {
    vertexs[i]->path = NULL;
    vertexs[i]->holder = MAX_INT_VALUE;
    vertexs[i]->processing=false;
}

(this->*weight_filler)();

Vertex* v=ini;
v->holder = 0;
v->processing = true;

vector<Vertex*> pq;
pq.push_back(v);
make_heap(pq.begin(),pq.end(),pq_order);

while(!pq.empty()){

    v=pq.front();
    pop_heap(pq.begin(),pq.end());
    pq.pop_back();

    for(unsigned int u=0; u < v->adj.size(); u++){

        Vertex* w = v->adj[u]->dest;

        if((v->holder+v->adj[u]->weight) < w->holder){

            w->holder=v->holder + v->adj[u]->weight;
            w->path=v;

            if(!w->processing){

                w->processing=true;
                pq.push_back(w);
            }
        }

        make_heap(pq.begin(),pq.end(),pq_order);
    }
}

return;}

错误在make_heap中,我无法弄清楚,任何帮助都将不胜感激。

这是我传递给make_heap的函数:

bool Graph::regular_PqOrder(const Vertex* &v, const Vertex* &u){
return v->holder > u->holder;}

这就是我所说的算法:

dijkstraAlg(i,f,&Graph::price_WeightFiller,&Graph::regular_PqOrder);

如果您需要更多信息,请告诉我,我进行编辑。 谢谢朋友的

您传递的是错误的类型。 std::make_heap将函子作为第三个元素,应满足Compare的需求,即您需要:

bool operator()(const Type1&, const Type2&) const;

您正在传递pq_order类型为:

bool(Graph::*)(const Vertex* &, const Vertex* &)

那是一个指向成员的指针,没有Graph类型的对象就无法调用。 因此,有关“类型必须使用'。 '或'-> '来调用指向成员的指针”的错误。 最简单的方法是简单地提供该对象,在您的情况下是this

using namespace std::placeholders;
std::make_heap(pq.begin(), pq.end(), 
    std::bind(pq_order, this, _1, _2));

另外,由于regular_PqOrder实际上并不依赖于Graph的其他方法的任何成员,因此也可以将其设为静态:

class Graph { 
public:
    static bool regular_PqOrder(const Vertex* &v, const Vertex* &u) 
    {
        return v->holder > u->holder;
    }
};

并将Graph::regular_PqOrder作为函数指针而不是方法指针传递。

我已将您的问题简化为:

#include <algorithm>
#include <vector>

using namespace std;

class Vertex
{};

class Graph
{
public:
    void dijkstraAlg(Vertex* ini, Vertex* fin, void(Graph::*weight_filler)(void), 
                                               bool(Graph::*pq_order)(const Vertex*, const Vertex*))
    {
        (this->*weight_filler)();

        struct Comparator
        {
        private:

            Graph* m_g;
            bool(Graph::*m_fn)(const Vertex*, const Vertex*);
        public:
            Comparator(Graph* g, bool(Graph::*fn)(const Vertex*, const Vertex*)) : m_g(g), m_fn(fn)
            {}

            bool operator()(const Vertex* one, const Vertex* two) const
            {
                return (m_g->*m_fn)(one, two);
            }
        };

        Comparator comparator(this, pq_order);

        vector<Vertex*> pq;
        std::make_heap(pq.begin(), pq.end(), comparator);
    }

    void weight_filler1()
    {        
    }
    bool pq_order1(const Vertex*, const Vertex*)
    {
        return false;
    }

};

int main()
{
    Graph g;
    g.dijkstraAlg(nullptr, nullptr, &Graph::weight_filler1, &Graph::pq_order1);

    return 0;
}

问题是: std::make_heap需要一个函数指针-在您的情况下,您正在传递一个指向成员函数的指针,因此出现了问题。

您可以更改dijkstraAlg的声明以仅接受静态函数指针pq_order或将pq_order包装在结构中以使其本身成为可调用实体,就像我所做的那样。

注意:您必须修正对pq_order指针的引用,以使pq_order make_heap可以编译

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM