繁体   English   中英

优先级队列如何在内部工作?

[英]c++ - Priority Queue - How does it work internally?

假设我有以下优先级队列声明:

    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;

我想知道是否有人可以花时间解释我的编译器如何解释比较类。

  • 为什么需要重载()运算符?
  • 另外,在比较过程中使用()运算符在哪里?

感觉有点奇怪,尤其是因为我对模板和所有OOP概念都不是很满意。

为什么我们需要声明单个对象的类型和容器类型?

您不需要使operator()重载。 您可以声明自定义方法:

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;
}

更新 :正如@WhozCraig指出的:可以在不重载operator()的情况下使用此对象,但是编译器将面临内联operator()比较函数而不是运行时提供的解引用比较函数的更简单情况。

您实际上是在询问函数对象(或函子)。 函数对象是一个重载operator() 您可以将其当作函数来使用。 该标准提供了一些比较函子(例如您的orderByRewards )。 例如, std::less看起来像这样:

template <class T>
struct less {
  constexpr bool operator()(const T &lhs, const T &rhs) const 
  {
    return lhs < rhs;
  }
};

如我们所见,重载的operator()仅使用<比较两个参数,然后返回布尔结果。 要使用它,您需要创建一个std::less类型的对象,然后在其上使用函数调用语法:

std::less<int> compare;
assert(compare(5, 7) == true);

即使compare是一个对象,我们也可以像compare(5, 7)的函数一样使用它。

现在我们知道您的类型orderByRewards是函数对象类型。 您将其作为std::priority_queue的模板类型参数传递。 然后,当需要比较队列中的元素时, std::priority_queue的实现可以创建此比较函数对象的对象。

考虑一个更简单的示例:

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;
    }
  }
};

这是一个愚蠢的例子,但可以理解这一点。 我们可以这样使用:

foo<int, std::less<int>> my_foo;
my_foo.bar(5, 7); // Will print true

我们可以通过传递foo任意比较函子类型来配置foo ,使其成员函数bar可以实例化和使用。

因此,以同样的方式,通过为std::priority_queue提供一个比较函子类型来配置std::priority_queue ,它可用于对队列中的元素进行排序。 这就是它确定元素之间优先级的方式。 实际上, std::priority_queue的默认模板类型参数是std::less

查看std::priority_queue的定义并从那里开始工作可能是最有意义的。

template <class T, class Container = vector<T>, 
          class Compare = less<typename Container::value_type> >
class priority_queue {

这表示Compare是某种类型,默认为std::less<T> ,因为T =基础容器的value_type。 这弥补了您可能会有些疯狂的事情(例如创建一种类型的priority_queue)但使基础容器容纳另一种类型的可能性的可能性(尽管并非偶然,但这种可能性不大)。

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.
};

简而言之,它是一种仅由一个公开可用的操作定义的类型: operator() ,可以传递要比较的两个项目,并返回bool以指示第一个是否小于第二个。

因为那是什么std::priority_queue希望使用,无论您必须提供基本支持相同的函数调用的语法和语义(例如, operator()应采取const参数和本身应该是const修饰)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM