混淆了定义自定义优先级队列和使用C++中的make_heap等方法初始化堆之间的区别

Confused of the difference between defining a custom priority queue and initializing a heap using methods like make_heap in C++

本文关键字:heap make 方法 初始化 区别 之间 中的 C++ 自定义 定义 优先级      更新时间:2023-10-16

我试图解决一个编码问题,该问题要求我使用堆来按特定顺序获取项。当我试图使用自定义priority_queue和make_heap来实现解决方案时,我发现我们在自己的比较器中传递的方式是不同的,而且令人困惑。

c++.com说:

priority_queue (const Compare& comp = Compare(), const Container& ctnr = Container());

Comp是用于对堆进行排序的比较对象。这可能是一个函数指针或函数对象,能够通过比较其两个参数来执行严格的弱排序。

void make_heap (RandomAccessIterator first, RandomAccessIterator last,
              Compare comp );

这里comp是一个二进制函数,它接受范围中的两个元素作为参数,并返回一个可转换为bool的值。它可以是函数指针,也可以是函数对象。

我对这里使用2 comp的区别感到困惑,当我试图实现我的代码时:

// first I define a functor and a static function, both used to be passed as the comp argument;
class isGreater {
    public:
        isGreater() {}
        inline bool operator() (const ListNode* l1, const ListNode* l2) const {
            return l1->val >= l2->val;
        }
}; 
static bool isLarger(const ListNode* l1, const ListNode* l2) {
    return l1->val >= l2->val;    
}
// then I tried several ways to define a custom pq and heap:
// correct
priority_queue<ListNode*, std::vector<ListNode*>, isGreater> p;
// wrong, error: data member instantiated with function type 
// 'value_compare'(aka 'isGreater ()')
priority_queue<ListNode*, std::vector<ListNode*>, isGreater()> p;
// wrong, passing a function pointer like this is not allowed
// error: template argument for template type parameter must be a type
priority_queue<ListNode*, std::vector<ListNode*>, isLarger> p;
// correct
make_heap(v.begin(), v.end(), isGreater());
// correct, here passing a function pointer like this is allowed
make_heap(v.begin(), v.end(), isLarger); 
// wrong, the "()" is needed, different from how we define priority queue
make_heap(v.begin(), v.end(), isGreater);

我对我们把comp作为论据的不同方式感到困惑。有人能帮我解这些谜题吗?

为了了解发生了什么,您需要了解isGreaterisGreater() 之间的区别

  • isGreater是一个类型的名称。它可以去类型可以去的地方,即进入模板参数(三角括号)和声明
  • isGreater()是一个构造函数调用,它生成类型为isGreater对象。它可以放在表达式可以放的任何地方,例如,它可以用作函数参数

现在错误应该清楚了:不允许使用类型名isGreater来代替对象表达式isGreater(),反之亦然。

模板中的比较函数是类型。构造函数或make_heap函数中的比较函数是一个可调用的对象

isLarger函数是一个可调用的对象而不是类型,因此不能将其用作std::priority_queue的模板参数。

另一方面,类isGreate是一种类型,可用于创建可调用对象。