【发布时间】:2021-05-20 13:05:30
【问题描述】:
我有一组指针,我希望该组按特定顺序排序。
我想出了这段代码,它按预期工作:
#include <string>
#include <iostream>
#include <set>
class Data
{
public:
std::string name;
int data;
bool operator < (const Data& other) const
{
return name < other.name;
}
bool operator < (const Data* other) const
{
std::cout << "never called ";
return name < other->name;
}
};
struct DataComparator
{
bool operator()(const Data* lhs, const Data* rhs) const
{
return *lhs < *rhs;
}
};
int main() {
Data d1{ "bb", 1 };
Data d2{ "cc", 2 };
Data d3{ "aa", 3 };
std::set<Data*, DataComparator> s;
s.insert(&d1);
s.insert(&d2);
s.insert(&d3);
// print set members sorted by "name" field
for (auto& d : s)
std::cout << d->name << "\n";
return 0;
}
困扰我的是我需要使用DataComparator 结构来实现自定义排序顺序。我希望比较器成为Data 类的一部分。我尝试实现bool operator < (const Data* other) const 类成员并将集合声明为std::set<Data*> s;,但现在operator < 函数(不出所料)从未被调用,并且排序顺序是按指针地址。
有没有办法直接在Data 类中实现自定义比较器,所以我可以这样:
std::set<Data*> s;
...
// print set members sorted by "name" field
for (auto& d : s)
std::cout << d->name << "\n";
【问题讨论】:
-
你知道你的
bool Data::operator < (const Data* other) const隐含const Data&作为它的第一个参数吗?这就是它从未被调用的原因。 -
但是该集合是指针(Data*),而不是 Data 本身。所以比较器需要是指针。您不能隐式使用要使用的 Data 类的比较运算符来代替指针比较(无需像您那样创建旁路运算符)
-
可能需要专门化
std::less<Data*>,因为这是std::set使用的默认参数。 -
@Dialecticus Extending the namespace
std: "t 仅当声明依赖于至少一种程序定义类型时,才允许将任何标准库类模板的模板特化添加到命名空间 std。 . " 指向用户定义类型的指针算作程序定义类型吗? -
@FrançoisAndrieux 不,指针永远不是用户定义的