【问题标题】:Set of pointers to objects with custom comparator指向具有自定义比较器的对象的指针集
【发布时间】: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 &lt; (const Data* other) const 类成员并将集合声明为std::set&lt;Data*&gt; s;,但现在operator &lt; 函数(不出所料)从未被调用,并且排序顺序是按指针地址。

有没有办法直接在Data 类中实现自定义比较器,所以我可以这样:

 std::set<Data*> s;
 ...         
 // print set members sorted by "name" field
 for (auto& d : s)
   std::cout << d->name << "\n";

【问题讨论】:

  • 你知道你的bool Data::operator &lt; (const Data* other) const 隐含const Data&amp; 作为它的第一个参数吗?这就是它从未被调用的原因。
  • 但是该集合是指针(Data*),而不是 Data 本身。所以比较器需要是指针。您不能隐式使用要使用的 Data 类的比较运算符来代替指针比较(无需像您那样创建旁路运算符)
  • 可能需要专门化std::less&lt;Data*&gt;,因为这是std::set 使用的默认参数。
  • @Dialecticus Extending the namespace std : "t 仅当声明依赖于至少一种程序定义类型时,才允许将任何标准库类模板的模板特化添加到命名空间 std。 . " 指向用户定义类型的指针算作程序定义类型吗?
  • @FrançoisAndrieux 不,指针永远不是用户定义的

标签: c++ stdset


【解决方案1】:

有没有办法直接在 Data 类中实现自定义比较器,这样我就可以拥有 [stuff]:

没有。我会写一个模板

template <typename T>
struct PointerLess
{
    bool operator()(const T * lhs, const T * rhs) const
    {
        return *lhs < *rhs;
    }
};

然后你会有std::set&lt;Data*, PointerLess&lt;Data&gt;&gt; 等等。

【讨论】:

  • 这不是我想要的,但仍然比我的解决方案好一些。顺便说一句,您在...T * rhs) 之后忘记了const
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多