C ++中的优先级队列,带有自定义类和lambda表达式

时间:2015-07-22 20:35:59

标签: c++ stl priority-queue

我正在学习如何在C ++中使用STL。我正在尝试使用std::priority_queue实现堆。这是我的尝试:

#include<vector>
#include<algorithm>
#include<iostream>
#include<queue>
#include<stack>
#include<functional>
using namespace std;

struct data {
    int first;
    int second;
};

class compare {
public:
    bool operator()(data &a ,data &b)
    {
         if(a.first < b.first) return true;
         else false;
    }
};

int main()
{   
    priority_queue <data , vector<data>, compare> heap;
    data temp2[] = { {5,19},{2,7},{90,9},{12,6} };

    for(int i = 0; i < 4; ++i)
    {       
       heap.push(temp2[i]);
    }

    while(heap.empty() == false)
    {
        cout << heap.top().first << endl;;
        heap.pop();
    }       
}

当我在visual studio 2012上运行此代码时,它会在推送第二个元素时崩溃。错误如下:

Program: C:\WINDOWS\system32\MSVCP110D.dll
File: c:\program files (x86)\microsoft visual studio 11.0\vc\include\algorithm
Line: 2463
Expression: invalid operator<

但是当我在ideone中运行相同的代码时,它可以工作,但输出是错误的。 Ideone link

1. 有人可以指出我出错的地方吗?

在同一个问题中再添加一个问题:

2. 如何使用compare函数编写这个lambda表达式?

2 个答案:

答案 0 :(得分:3)

您不应忽略编译器发出的警告:

warning C4715: 'compare::operator()' : not all control paths return a value

那是因为else false;没有返回任何内容,它只是评估表达式false并丢弃结果。它应该是else return false;

当然,更简单的选择就是说return a.first < b.first;

回复您更新的问题:

在这里使用lambda不会那么多,因为你需要将functor的类型指定为std::priority_queue的模板参数,并将functor本身作为构造函数初始化时的参数{ {1}}(在使用heap的版本中,仿函数是默认构造的; lambdas不是默认构造的。)

但是,既然你问过,这里是:

compare

我对原始代码进行了一些修改;在正确性(#include <iostream> #include <queue> #include <vector> struct data { int first; int second; }; int main() { auto cmp = [](const data& a, const data& b) { return a.first < b.first; }; // For Visual C++ 2013 and beyond: // std::vector<data> temp = {{5, 19}, {2, 7}, {90, 9}, {12, 6}}; // std::priority_queue<data, std::vector<data>, decltype(cmp)> heap{cmp, std::move(temp)}; // For Visual C++ 2012 (doesn't support list-initialization for non-aggregates): data temp[] = {{5, 19}, {2, 7}, {90, 9}, {12, 6}}; std::priority_queue<data, std::vector<data>, decltype(cmp)> heap(std::begin(temp), std::end(temp), cmp); while(!heap.empty()) { std::cout << heap.top().first << '\n'; heap.pop(); } } )和效率方面,将它们作为改进的建议。

答案 1 :(得分:2)

您的比较功能在return之前缺少false。这应该有效:

class compare{
public:
    bool operator()(data &a, data &b)
    {
        if (a.first < b.first) 
            return true;
        else 
            return false;
    }
};

VS提供编译警告但不是错误。正如巴里指出的那样,这不是一个错误。有关详细信息,请参阅此SO答案https://stackoverflow.com/a/1610454/3154588。 (我仍然认为这应该是一个编译错误,因为拥有一个不返回值的代码路径,总是错的 - 至少对于我编写的所有代码都是错误的!)