Создание минимальной кучи из приоритетной очереди STL

Я создаю минимальную кучу из очереди приоритетов stl. Вот мой класс, который я использую.

class Plane
{
  private :
    int id ;
    int fuel ;
 public:
    Plane():id(0), fuel(0){}
    Plane(const int _id, const int _fuel):id(_id), fuel(_fuel) {}

    bool operator > (const Plane &obj)
    {
        return ( this->fuel > obj.fuel ? true : false ) ;
    }

} ;

В основном я создаю экземпляр объекта таким образом.

 priority_queue<Plane*, vector<Plane*>, Plane> pq1 ;
 pq1.push(new Plane(0, 0)) ;

Я получаю сообщение об ошибке от xutility, которое не могу понять.

d:\microsoft visual studio 10.0\vc\include\xutility(674): ошибка C2064: термин не оценивается как функция, принимающая 2 аргумента

Любая помощь в его решении будет оценена по достоинству.


person Sasha    schedule 07.12.2012    source источник


Ответы (2)


Третий параметр шаблона должен быть бинарным функтором, принимающим teo Plane*. Ваш класс Plane этого не обеспечивает.

Вам нужно что-то в форме

struct CompPlanePtrs
{
  bool operator()(const Plane* lhs, const Plane* rhs) const {
    return lhs->fuel > rhs->fuel ;
  }
};
person juanchopanza    schedule 07.12.2012
comment
Я не могу сделать это с оператором ›?. сделать его другом? С оператором() тоже не все в порядке. - person Sasha; 07.12.2012
comment
@ Саша, проблема в том, что тебе нужно сравнивать указатели с Planes, а не с Planes. Вы не можете перегружать operator> для указателей. - person juanchopanza; 07.12.2012

Если вы откажетесь от использования указателей (которые излишни для ваших простых структур), вы можете использовать std::greater из шапки functional:

std::priority_queue<Plane, std::vector<Plane>, std::greater<Plane> > pq1;
pq1.push(Plane(0, 0));

В настоящее время вы подаете Plane в качестве типа сравнения. Это не сработает, так как тип сравнения должен быть типом функционального объекта, т. е. он должен иметь operator(), который выполняет сравнение. Plane такого члена нет (и добавлять его только для этой цели было бы плохой идеей).

std::greater имеет соответствующий метод, реализованный с точки зрения вашего operator>. Однако он не работает с указателями, потому что тогда он использует сравнение указателей (на основе адресов памяти).

Кстати, обратите внимание, что ваша функция сравнения может быть выражена более кратко как

bool operator>(const Plane &other)
{
    return fuel > other.fuel;
}
person Fred Foo    schedule 07.12.2012
comment
Хорошо, но для моего ответа этот ответ нуждается в объяснении того, почему тип элемента является неподходящим типом компаратора и, следовательно, почему исходный код OP не скомпилировался. :-) - person Lightness Races in Orbit; 07.12.2012
comment
Он отлично работает, но я не могу понять причину этого, как упоминает @Lightness Races in Orbit. - person Sasha; 07.12.2012
comment
@larsmans, как он узнает, что он должен заказывать в соответствии с моим топливом? - person Sasha; 07.12.2012
comment
std::greater вызовет ваш operator>. Он просто знает, что делать. - person Lightness Races in Orbit; 07.12.2012
comment
@LightnessRacesinOrbit: очень жаль, что вы не заметили самую серьезную ошибку из всех: std::greater будет сравнивать указатели. Изменил ответ, снова. - person Fred Foo; 07.12.2012
comment
@larsmans Но мне приходится создавать динамический объект в каждую единицу времени. Я не могу просто сбросить указатели. - person Sasha; 07.12.2012
comment
@Sasha: тогда другой ответ - то, что тебе нужно. Вы не можете перегрузить operator> по указателям, потому что он уже определен. - person Fred Foo; 07.12.2012