具有自定义对象的 C++ 优先级队列
C++ Priority Queue with customized object
我试图了解比较器如何为优先级队列工作,我做了几个测试:
测试 1:创建比较器 class,并使用 priority_queue<T, vector<T>, cmp>
它总是工作正常
测试 2:
struct test {
int a = 0;
};
bool operator<(const test& lhs, const test& rhs) {
return lhs.a < rhs.a;
}
int main()
{
priority_queue<test> pq;
}
这按预期工作。
测试 3:将测试 2 放入 class
class T{
struct test {
int a = 0;
};
bool operator<(const test& lhs, const test& rhs) {
return lhs.a < rhs.a;
}
};
编译错误:
'bool T::operator<(const T::test&, const T::test&)' must take exactly one argument
似乎编译器认为我正在为 class T 重载运算符 <。如果我真的需要嵌套 classes,还有其他方法可以实现吗?
测试 4:重载运算符<
struct test {
int a = 0;
bool operator<(const test& rhs) {
return a < rhs.a;
}
};
int main()
{
vector<test> v;
sort(v.begin(), v.end()); // No error
set<test> s; // No error
priority_queue<test> pq; // Compiling error
}
只有priority_queue会报错:
'passing 'const test*' as 'this' argument discards qualifiers'
我不知道为什么这适用于排序和设置但不适用于优先级队列。
operator<
必须有两个参数,而当你使它成为 class T
的成员时,它隐含地得到 this
作为第三个参数,因此测试 3 中的错误:
class T {
bool operator<(const test& lhs, const test& rhs) { // error
return lhs.a < rhs.a;
}
};
要解决此问题,请在嵌套的 test
class:
中定义 operator<
class T {
public:
struct test {
int a = 0;
friend bool operator<(const test& lhs, const test& rhs) {
return lhs.a < rhs.a;
}
};
};
或在命名空间范围内。
在测试 4 中 operator<
应该是 const
:
struct test {
int a = 0;
bool operator<(const test& rhs) const {
return a < rhs.a;
}
};
priority_queue 的比较器与任何其他比较器一样工作。应该可以参与表达式
if (compare(element1, element2))
默认实现缩减为
if (element1 < element 2) ....
你在 3 中所做的导致
if ( tObject.operator<(anotherTObject, yetAnotherTObject))
所以你的
bool T::operator<(const test& lhs, const test& rhs) {
return lhs.a < rhs.a;
}
确实应该与对象本身进行比较,例如
bool T::operator<(const test& rhs) const {
auto lhs = *this;
return lhs.a < rhs.a;
}
最后一个 const 的作用类似于 vitauts 合理答案中第一个参数的 const。
我试图了解比较器如何为优先级队列工作,我做了几个测试:
测试 1:创建比较器 class,并使用 priority_queue<T, vector<T>, cmp>
它总是工作正常
测试 2:
struct test {
int a = 0;
};
bool operator<(const test& lhs, const test& rhs) {
return lhs.a < rhs.a;
}
int main()
{
priority_queue<test> pq;
}
这按预期工作。
测试 3:将测试 2 放入 class
class T{
struct test {
int a = 0;
};
bool operator<(const test& lhs, const test& rhs) {
return lhs.a < rhs.a;
}
};
编译错误:
'bool T::operator<(const T::test&, const T::test&)' must take exactly one argument
似乎编译器认为我正在为 class T 重载运算符 <。如果我真的需要嵌套 classes,还有其他方法可以实现吗?
测试 4:重载运算符<
struct test {
int a = 0;
bool operator<(const test& rhs) {
return a < rhs.a;
}
};
int main()
{
vector<test> v;
sort(v.begin(), v.end()); // No error
set<test> s; // No error
priority_queue<test> pq; // Compiling error
}
只有priority_queue会报错:
'passing 'const test*' as 'this' argument discards qualifiers'
我不知道为什么这适用于排序和设置但不适用于优先级队列。
operator<
必须有两个参数,而当你使它成为 class T
的成员时,它隐含地得到 this
作为第三个参数,因此测试 3 中的错误:
class T {
bool operator<(const test& lhs, const test& rhs) { // error
return lhs.a < rhs.a;
}
};
要解决此问题,请在嵌套的 test
class:
operator<
class T {
public:
struct test {
int a = 0;
friend bool operator<(const test& lhs, const test& rhs) {
return lhs.a < rhs.a;
}
};
};
或在命名空间范围内。
在测试 4 中 operator<
应该是 const
:
struct test {
int a = 0;
bool operator<(const test& rhs) const {
return a < rhs.a;
}
};
priority_queue 的比较器与任何其他比较器一样工作。应该可以参与表达式
if (compare(element1, element2))
默认实现缩减为
if (element1 < element 2) ....
你在 3 中所做的导致
if ( tObject.operator<(anotherTObject, yetAnotherTObject))
所以你的
bool T::operator<(const test& lhs, const test& rhs) {
return lhs.a < rhs.a;
}
确实应该与对象本身进行比较,例如
bool T::operator<(const test& rhs) const {
auto lhs = *this;
return lhs.a < rhs.a;
}
最后一个 const 的作用类似于 vitauts 合理答案中第一个参数的 const。