【问题标题】:priority_queue in c++ with custom comparatorC++ 中的 priority_queue 与自定义比较器
【发布时间】:2017-05-26 02:26:49
【问题描述】:

我创建了一个 priority_queue 并定义了一个自定义比较器(一个结构),它在构造函数中采用一个 2D 向量。它编译并成功运行到声明该优先级队列的地步。但是,如果我尝试将元素添加到优先级队列中,则会弹出错误:

错误:在 'minHeap' 中请求成员 'push',它是非类类型 'std::priority_queue, std::vector >, MyComparator>(MyComparator)' minHeap.push(make_pair(0, 1));

我想知道是什么问题?

#include <iostream>
#include <vector>
#include <queue>
using namespace std;



struct MyComparator{
    vector<vector<int>> array2D;

    MyComparator(const vector<vector<int>>& arrays){
        array2D = arrays;   
    }

    bool operator()(const pair<int, int> &p1, const pair<int, int> &p2){
        return array2D[p1.second][p1.first] > array2D[p2.second][p2.first];
    }
};


int main() {
    vector<vector<int>> arrays = {{1, 3, 5, 7}, {2, 4, 6},{0, 8, 9, 10, 11}};
    priority_queue<pair<int, int>, vector<pair<int, int>>, MyComparator> minHeap(MyComparator(arrays));

//运行良好,上面没有错误

    minHeap.push(make_pair(0, 1)); //pop me error
    return 0;
}

【问题讨论】:

标签: c++


【解决方案1】:

这是因为您的优先队列初始化被视为函数声明而不是变量声明。有关原因,请参阅https://en.wikipedia.org/wiki/Most_vexing_parse

将初始化优先级队列的行更改为此

priority_queue<pair<int, int>, vector<pair<int, int>>, MyComparator> minHeap{MyComparator(arrays)}; 

它应该可以正常工作。

它现在起作用的原因是因为{} 不再模棱两可了。 {} 是在 C++11 中作为构造对象的一种方式引入的,在许多情况下,它比括号更可取来初始化变量。更多内容见Why is list initialization (using curly braces) better than the alternatives?

注意 以后,请始终记住在启用警告标志的情况下进行编译。通常推荐的是-Werror-Wall-pedantic。当您启用这些标志时,编译器会提醒您代码中存在的歧义(最令人头疼的解析)。

【讨论】:

  • 这应该可以。如果没有,请尝试对 minHeap 和未命名的 MyComparator 进行统一初始化,并查看:priority_queue&lt;pair&lt;int, int&gt;, vector&lt;pair&lt;int, int&gt;&gt;, MyComparator&gt; minHeap{MyComparator{arrays}};
【解决方案2】:

这个问题被称为最棘手的解析。

priority_queue<pair<int, int>, vector<pair<int, int>>, MyComparator> minHeap(MyComparator(arrays));

在这里,编译器无法确定这是函数签名还是构造函数的调用。消除这种歧义的常用方法是添加一对额外的括号:

priority_queue<pair<int, int>, vector<pair<int, int>>, MyComparator> minHeap((MyComparator(arrays)));

Curious 的回答也是正确的,但是对于使用大括号进行构造函数调用有不同的看法。

【讨论】:

  • 这行得通!我从来没有遇到过这种问题,但现在我知道了。谢谢!我很高兴我学到了一些东西!
猜你喜欢
  • 2013-04-13
  • 1970-01-01
  • 1970-01-01
  • 2011-05-10
  • 1970-01-01
  • 1970-01-01
  • 2016-05-13
  • 1970-01-01
  • 2018-12-17
相关资源
最近更新 更多