c ++中的priority_queue与自定义比较器

时间:2017-05-26 02:26:50

标签: c++

我创建了一个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;
}

2 个答案:

答案 0 :(得分:3)

这是因为您的优先级队列初始化被视为函数声明而不是变量声明。有关原因,请参阅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。当您启用这些标志时,编译器将提醒您代码中存在的歧义(最令人烦恼的解析)。

答案 1 :(得分:1)

这个问题被称为最令人烦恼的解析。

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

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