2015-04-22 165 views
0

我正在開發這個程序,用堆實現來運行Dijkstra的算法,並且我希望它能夠儘可能多功能,所以我使用函數指針以便避免代碼重複。這是它彈出的錯誤。我使用STL make_heap傳遞一個函數指針作爲stl中的比較器make_heap C++

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

只是如果你需要更多的信息告訴我,我編輯。 謝謝朋友的

+0

這是怎麼被稱爲?你應該追加和功能被傳遞給你的算法 – Sarang

+0

已經編輯。謝謝你的時間 –

回答

1

我已經簡化了你的問題:

#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_ordermake_heap編譯反正

2

您傳遞錯誤的類型。 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現在通過一個函數指針,而不是指針到方法。

相關問題