2016-04-08 57 views
3

我有一個節點類的功能如何將std :: pop_heap接受的函數指針設置爲Compare?

static bool HasGreaterF(const Node& a, const Node& b); 
static bool HasGreaterF(const std::shared_ptr<Node>& a, const std::shared_ptr<Node>& b); 

然後使一個向量作爲堆和想使用第二功能進行比較。這是行不通的,因爲函數指針不能與一個函數匹配。如果我刪除它的第一個功能。如何使它與兩個函數一起工作?

std::vector<std::shared_ptr<Node>> openlist_min_f; 
std::pop_heap(openlist_min_f.begin(), openlist_min_f.end(), &Node::HasGreaterF); 

回答

3

使用static_cast指定它:

std::pop_heap(openlist_min_f.begin(), openlist_min_f.end(), 
       static_cast<bool (*)(const std::shared_ptr<Node>&, const std::shared_ptr<Node>&)> 
       (&Node::HasGreaterF)); 

或者使用lambda包裝作爲@大衛建議,因爲該功能不應該在這種情況下,不明確的。

std::pop_heap(openlist_min_f.begin(), openlist_min_f.end(), 
       [](const auto& l, const auto& r){ return Node::HasGreaterF(l, r); }); 
+1

C++有時是一個痛苦的屁股。這是否少了字符:'[](const auto&l,const auto&r){return Node :: HasGreaterF(l,r); }'......可能不是。 – David

+0

@大衛好點。 – songyuanyao

2

,你不能用它作爲 - 是的原因是pop_heap必須根據你傳遞的比較器的類型,重載函數沒有一個類型。有一些上下文可以使用重載函數的名稱,而不是簡單地調用它們,但作爲參數傳遞給函數模板不是其中之一。在這種情況下,你必須明確說明你的意思是其中HasGreaterF

您可以使用一個static_cast(如前所述),或者只是把它包在一個lambda:

std::pop_heap(openlist_min_f.begin(), openlist_min_f.end(), 
    [](const auto& lhs, const auto& rhs) { return Node::HasGreaterF(lhs, rhs); }); 

拉姆達具有在於它在我的經驗被內聯的可能性更大優勢(儘管兩者是despressingly冗長)。您可以隨時宏觀IFY的拉姆達包裹在C++ 14:

#define WRAP_FUN(f) [](auto&&... args) -> decltype(auto) { return f(std::forward<decltype(args)>(args)...); } 

,使這成爲:

std::pop_heap(openlist_min_f.begin(), openlist_min_f.end(), WRAP_FUN(Node::HasGreaterF)); 
相關問題