在 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
takes a functor as the third element, which should satisfy the requirements of Compare
,你需要的是:
bool operator()(const Type1&, const Type2&) const;
您正在传递 pq_order
类型:
bool(Graph::*)(const Vertex* &, const Vertex* &)
这是一个指向成员的指针,没有 Graph
类型的对象是不可调用的。因此,关于 "Type must use '.' or '->' to call pointer-to-member" 的错误。最简单的方法是简单地提供该对象,在您的情况下是 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
中指针的引用,以便 make_heap
无论如何都能编译
我正在将此程序开发为 运行 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
takes a functor as the third element, which should satisfy the requirements of Compare
,你需要的是:
bool operator()(const Type1&, const Type2&) const;
您正在传递 pq_order
类型:
bool(Graph::*)(const Vertex* &, const Vertex* &)
这是一个指向成员的指针,没有 Graph
类型的对象是不可调用的。因此,关于 "Type must use '.' or '->' to call pointer-to-member" 的错误。最简单的方法是简单地提供该对象,在您的情况下是 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
中指针的引用,以便 make_heap
无论如何都能编译