Я знаю, что есть похожие темы, но потратив час на попытки заставить мою программу работать, я решил обратиться за помощью.
Прежде всего. Я думал, что хорошо знаю c ++, так как попробовал что-то очень простое в PHP (язык программирования, который я знаю лучше всего), но очень сложное в c ++ (по крайней мере, очень сложное для меня). Поэтому я хочу создать priority_queue указателей структуры. Очевидно, что мне нужно создать собственную функцию сравнения. Итак, я попробовал этот код:
#include <iostream>
#include <list>
#include <queue>
using namespace std;
typedef struct MI
{
int nr;
int koszt;
bool operator<(const MI& a, const MI& b) {
return a.koszt > b.koszt;
}
} miasto, *miasto_wsk;
int main()
{
priority_queue<miasto_wsk> q;
miasto_wsk mi;
mi = new miasto;
mi->nr = 1;
mi->koszt = 2;
q.push(mi);
}
И когда я попытался скомпилировать свою программу, я закончил с ошибкой компиляции:
test.cpp:11:44: error: ‘bool MI::operator<(const MI&, const MI&)’ must take exactly one argument
Можете ли вы объяснить мне, что я делаю неправильно, и объяснить, как все эти вещи со структурами сравнивают работы (или дать мне хороший учебник / статью, которая объясняет это с самого начала)
РЕДАКТИРОВАТЬ:
Я изменил свой код на это:
#include <iostream>
#include <list>
#include <queue>
using namespace std;
typedef struct miasto
{
int nr;
int koszt;
} *miasto_wsk;
bool myComparator(miasto_wsk arg1, miasto_wsk arg2) {
return arg1->koszt < arg2->koszt; //calls your operator
}
int main()
{
priority_queue<miasto_wsk, vector<miasto_wsk>, myComparator> q;
miasto_wsk mi;
mi = new miasto;
mi->nr = 1;
mi->koszt = 2;
q.push(mi);
}
И теперь я получаю эту ошибку MSG:
test.cpp: In function ‘int main()’:
test.cpp:19:64: error: type/value mismatch at argument 3 in template parameter list for ‘template<class _Tp, class _Sequence, class _Compare> class std::priority_queue’
test.cpp:19:64: error: expected a type, got ‘myComparator’
test.cpp:19:67: error: invalid type in declaration before ‘;’ token
test.cpp:24:7: error: request for member ‘push’ in ‘q’, which is of non-class type ‘int’
В чем проблема? Может быть, я должен использовать копии структур вместо указателей на структуры?
EDIT2
Этот код не вызывает ошибок компиляции:
#include <iostream>
#include <list>
#include <queue>
using namespace std;
typedef struct miasto
{
int nr;
int koszt;
bool operator< (const miasto& rhs)
{
koszt > rhs.koszt;
}
} *miasto_wsk;
int main()
{
priority_queue<miasto_wsk> q;
miasto_wsk mi;
mi = new miasto;
mi->nr = 1;
mi->koszt = 22;
q.push(mi);
}
Так что идея @Angew кажется неправильной.
EDIT3:
Это мой последний код. Он не только компилируется без ошибок, но и делает именно то, что я хочу. Большое спасибо @Angew
#include <iostream>
#include <list>
#include <queue>
using namespace std;
typedef struct miasto
{
int nr;
int koszt;
} *miasto_wsk;
struct MyComparator {
bool operator() (miasto_wsk arg1, miasto_wsk arg2) {
return arg1->koszt > arg2->koszt; //calls your operator
}
};int main()
{
//priority_queue<miasto_wsk, vector<miasto_wsk>, myComparator> q;
priority_queue<miasto_wsk, vector<miasto_wsk>, MyComparator> q;
miasto_wsk mi;
mi = new miasto;
mi->nr = 1;
mi->koszt = 22;
q.push(mi);
miasto_wsk mi1;
mi1 = new miasto;
mi1->nr = 2;
mi1->koszt = 50;
q.push(mi1);
miasto_wsk mi2;
mi2 = new miasto;
mi2->nr = 3;
mi2->koszt = 1;
q.push(mi2);
cout << q.top()->koszt << endl;
q.pop();
cout << q.top()->koszt << endl;
q.pop();
cout << q.top()->koszt << endl;
q.pop();
}
Здесь есть несколько вопросов.
Когда вы определяете оператор внутри класса, он автоматически принимает параметр типа класса в качестве первого аргумента, и вы не должны создавать для него параметр. Таким образом, вы либо оставляете оператор в классе, например:
struct MI {
bool operator< (const MI&);
};
или объявите оператора как отдельного:
struct MI {
//...
};
bool operator< (const MI&, const MI&);
Во-вторых, ваш priority_queue
магазины указатели на MI
, а не случаи MI
, так что оператор не будет вызываться в любом случае. Вы должны предоставить компаратор при определении очереди приоритетов, например так (РЕДАКТИРОВАНИЕ):
struct MyComparator {
bool operator() (miasto_wsk arg1, miasto_wsk arg2) {
return *arg1 < *arg2; //calls your operator
}
};
int main() {
priority_queue<miasto_wsk, vector<miasto_wsk>, MyComparator> q;
//...
}
В-третьих, это просто стиль: я бы посоветовал вам назвать класс напрямую miasto
вместо того, чтобы сделать это просто typedef
, Это более естественно в C ++.
Ошибка, если вы прочитаете ее снова, точно скажет вам, что не так: MI::operator<
Функция должна принимать только один аргумент вместо двух.
Если у вас есть operator<
в класс (как и вы), тогда функция принимает только один аргумент, и это другой объект для сравнения this
с. Если вы создаете operator<
как свободное положение функция (т.е. не является частью класса), то она должна принимать два аргумента.
Ваш оператор сравнения является функцией-членом, поэтому он должен принимать только один параметр для theRHS:
bool operator<(const MI& rhs) {
koszt > rhs.koszt;
}
Другой вариант — объявить его как функцию, не являющуюся членом:
struct MI {};
bool operator<(const MI& a, const MI& b) {
return a.koszt > b.koszt;
}
Используйте ключевое слово друга, чтобы поставить оператора < в глобальном масштабе
typedef struct MI
{
int nr;
int koszt;
friend bool operator<(const MI& a, const MI& b)
{
return a.koszt > b.koszt;
}
} miasto, *miasto_wsk;