[英]How to make appropriate function pointer accepted by std::pop_heap as Compare?
I have a Node class with the functions 我有一个带有这些函数的Node类
static bool HasGreaterF(const Node& a, const Node& b);
static bool HasGreaterF(const std::shared_ptr<Node>& a, const std::shared_ptr<Node>& b);
Then I make a vector as heap and would like to use the second function as Compare. 然后我将一个向量作为堆,并希望使用第二个函数作为比较。 This doesn't work, because the function pointer can't get matched to one function.
这不起作用,因为函数指针无法与一个函数匹配。 If I delete the first function it works.
如果我删除它的第一个功能。 How to make it work with both functions?
如何使它兼具两种功能?
std::vector<std::shared_ptr<Node>> openlist_min_f;
std::pop_heap(openlist_min_f.begin(), openlist_min_f.end(), &Node::HasGreaterF);
Use static_cast
to specify it: 使用
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));
Or use a lambda wrapper as @David suggested, since the functions should not be ambiguous in this case. 或者使用@David建议的lambda包装器,因为在这种情况下函数不应该是模糊的。
std::pop_heap(openlist_min_f.begin(), openlist_min_f.end(),
[](const auto& l, const auto& r){ return Node::HasGreaterF(l, r); });
The reason you can't use it as-is is that pop_heap
has to deduce the type of the comparator you pass in, and an overloaded function doesn't have one type. 你不能原样使用它的原因是
pop_heap
必须推断你传入的比较器的类型,而重载的函数没有一种类型。 There's contexts in which you can use the name of an overloaded function outside of simply calling them, but passing as an argument to a function template isn't one them. 在上下文中你可以使用重载函数的名称而不是简单地调用它们,但是作为参数传递给函数模板不是它们之一。 In this case, you have to explicitly state which
HasGreaterF
you mean. 在这种情况下,你必须明确地说明这
HasGreaterF
你的意思。
You can either use a static_cast
(as mentioned) or just wrap it in a lambda: 您既可以使用
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); });
The lambda has the advantage in that it has a greater likelihood of being inlined in my experience (though both are despressingly verbose). lambda的优势在于它更有可能在我的经验中被内联(虽然两者都是令人厌恶的冗长)。 You can always macro-ify the lambda wrapping in C++14:
你总是可以在C ++ 14中使用lambda包装:
#define WRAP_FUN(f) [](auto&&... args) -> decltype(auto) { return f(std::forward<decltype(args)>(args)...); }
so that this becomes: 这样就变成了:
std::pop_heap(openlist_min_f.begin(), openlist_min_f.end(), WRAP_FUN(Node::HasGreaterF));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.