[英]c++ - Priority Queue - How does it work internally?
Say I have this declaration of a priority queue: 假设我有以下优先级队列声明:
struct orderByRewards{
bool operator() (pair<int,pair<int,int> > a, pair<int, pair<int, int> > b){
return a.first < b.first;
}
};
priority_queue<pair<int,pair<int,int> >, vector<pair<int,pair<int,int> > >, orderByRewards> Q;
I was wondering if anybody could take their time and explain me how does the compiler interpret the compare class. 我想知道是否有人可以花时间解释我的编译器如何解释比较类。
It feels a little weird, especially since I am not really comfortable with templates and all OOP concepts. 感觉有点奇怪,尤其是因为我对模板和所有OOP概念都不是很满意。
Why do we need to declare the type of a single object and the container type ? 为什么我们需要声明单个对象的类型和容器类型?
You are not required to overfload the operator(). 您不需要使operator()重载。 You can declare your custom method:
您可以声明自定义方法:
typedef bool (*comp)(int,int);
bool compare(int a, int b)
{
return (a<b);
}
int main()
{
std::priority_queue<int,std::vector<int>, comp> pq(compare);
return 0;
}
Updated : As @WhozCraig pointed out: It is possible to use this object without overloading the operator() but the compiler will face an easier situation inlining operator() comparison function rather than runtime-provided dereferenced comparison function 更新 :正如@WhozCraig指出的:可以在不重载operator()的情况下使用此对象,但是编译器将面临内联operator()比较函数而不是运行时提供的解引用比较函数的更简单情况。
You're essentially asking about function objects (or functors). 您实际上是在询问函数对象(或函子)。 A function object is one that overloads
operator()
. 函数对象是一个重载
operator()
。 You can use such an object as though it were a function. 您可以将其当作函数来使用。 The standard provides a few comparison functors (like your
orderByRewards
). 该标准提供了一些比较函子(例如您的
orderByRewards
)。 For example, std::less
looks something like this: 例如,
std::less
看起来像这样:
template <class T>
struct less {
constexpr bool operator()(const T &lhs, const T &rhs) const
{
return lhs < rhs;
}
};
As we can see, the overloaded operator()
just compares the two arguments using <
and then returns the boolean result. 如我们所见,重载的
operator()
仅使用<
比较两个参数,然后返回布尔结果。 To use this, you need to create an object of type std::less
and then use the function call syntax on it: 要使用它,您需要创建一个
std::less
类型的对象,然后在其上使用函数调用语法:
std::less<int> compare;
assert(compare(5, 7) == true);
Even though compare
is an object, we were able to use it like a function in compare(5, 7)
. 即使
compare
是一个对象,我们也可以像compare(5, 7)
的函数一样使用它。
So now we know that your type orderByRewards
is a function object type. 现在我们知道您的类型
orderByRewards
是函数对象类型。 You are passing it as a template type argument of std::priority_queue
. 您将其作为
std::priority_queue
的模板类型参数传递。 The implementation of std::priority_queue
can then create objects of this comparison function object when it needs to compare elements within the queue. 然后,当需要比较队列中的元素时,
std::priority_queue
的实现可以创建此比较函数对象的对象。
Consider a simpler example: 考虑一个更简单的示例:
template <typename T, typename Comp>
struct foo {
void bar(T a, T b) {
Comp compare;
if (compare(a, b)) {
std::cout << "True" << std::endl;
} else {
std::cout << "False" << std::endl;
}
}
};
It's a silly example, but it gets the point across. 这是一个愚蠢的例子,但可以理解这一点。 We can use this like so:
我们可以这样使用:
foo<int, std::less<int>> my_foo;
my_foo.bar(5, 7); // Will print true
We were able to configure foo
, by passing it some arbitrary comparison functor type, that its member function bar
was able to instantiate and use. 我们可以通过传递
foo
任意比较函子类型来配置foo
,使其成员函数bar
可以实例化和使用。
So in the same way, you are configuration std::priority_queue
by giving it a comparison functor type that it can use to order elements within the queue. 因此,以同样的方式,通过为
std::priority_queue
提供一个比较函子类型来配置std::priority_queue
,它可用于对队列中的元素进行排序。 This is how it determines priority between elements. 这就是它确定元素之间优先级的方式。 In fact, the default template type argument for
std::priority_queue
is std::less
. 实际上,
std::priority_queue
的默认模板类型参数是std::less
。
Perhaps it would make the most sense to look at the definition of std::priority_queue
and work from there. 查看
std::priority_queue
的定义并从那里开始工作可能是最有意义的。
template <class T, class Container = vector<T>,
class Compare = less<typename Container::value_type> >
class priority_queue {
This says that Compare
is some type, and defaults to std::less<T>
, for T = the value_type of the underlying container. 这表示
Compare
是某种类型,默认为std::less<T>
,因为T =基础容器的value_type。 This compensates for the possibility that you might do something slightly insane like creating a priority_queue of one type, but have the underlying container hold another type (though that's not particularly likely, except by accident). 这弥补了您可能会有些疯狂的事情(例如创建一种类型的priority_queue)但使基础容器容纳另一种类型的可能性的可能性(尽管并非偶然,但这种可能性不大)。
std::less
, in turn, is defined like this: std::less
依次定义如下:
template <class T> struct less {
bool operator()(const T& x, const T& y) const;
// plus a few typedefs for the argument and return types.
};
In short, it's a type defined with only one publicly available operation: an operator()
that can be passed two items that it compares, and returns a bool
to indicate whether the first is less than the second. 简而言之,它是一种仅由一个公开可用的操作定义的类型:
operator()
,可以传递要比较的两个项目,并返回bool
以指示第一个是否小于第二个。
Since that's what std::priority_queue
expects to use, whatever you provide must support essentially the same function call-like syntax and semantics (eg, the operator()
should take const
arguments and should itself be const-qualified). 因为那是什么
std::priority_queue
希望使用,无论您必须提供基本支持相同的函数调用的语法和语义(例如, operator()
应采取const
参数和本身应该是const修饰)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.