我创建了一个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;
}
答案 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)));
好奇的回答也是正确的,但使用大括号进行构造函数调用有不同的看法。