【问题标题】:Why sort() function causes compilation error when it is used for set of class objects为什么 sort() 函数用于类对象集时会导致编译错误
【发布时间】:2013-04-10 12:33:54
【问题描述】:

我尝试为类重载< 运算符并调用函数如下:

bool Edge::operator<(Edge const & e) const {
    return this->GetCost() < e.GetCost();
}

在main()中

sort(edge_set.begin(),edge_set.end());

此外,我还尝试为对象编写一个简单的比较器函数,在 main.cpp 中定义并尝试调用sort(),但再次失败:

bool edge_comparator(Edge& e1, Edge& e2){
    return (e1.GetCost() < e2.GetCost());
}

在main()中

sort(edge_set.begin(),edge_set.end(), edge_comparator);

对于我尝试过的那些,我得到一个编译错误。我在这里做错了什么?如何对对象集进行排序?

【问题讨论】:

  • edge_set 是如何定义的?
  • edge_set 是如何定义的?如果 edge_set 是 std::set,那么 它已经排序了

标签: c++ sorting stl


【解决方案1】:

std::set 是已排序的关联容器,因此无法重新排序。排序标准适用于构造和元素插入。

编辑:您有一组Edge 指针。如果您希望根据自己的标准对其进行排序,您可以使用仿函数类型实例化一个 std::set,该仿函数在一对 Edge 指针之间执行小于比较作为第二个模板参数:

struct EdgePtrCmp
{
  bool operator()(const Edge* lhs, const Edge* rhs) const
  {
    return lhs->GetCost() < rhs->GetCost();
  }
}

然后

std::set<Edge*, EdgePtrCmp> s;

编辑2:问题又改了,不清楚是否处理的是一组指针。

【讨论】:

  • @Volkanİlbeyli 好的,请参阅编辑。但是现在的问题与原来的完全不同:)
  • 你不能重载operator&lt;,除非至少有一个参数是类类型(或者枚举也可以,不确定)。
  • @BenjaminLindley 当然,谢谢。我在想什么?我已将其更改为带有仿函数的示例。
【解决方案2】:

两个问题。首先,您不能对集合中的元素重新排序。它们的排序标准是在构造时确定的,它是对象的基本部分。这对于实现 O(log n) 查找、插入和删除是必要的,这是std::set 承诺的一部分。默认情况下,它将使用std::less&lt;Edge&gt;,它应该调用你的operator&lt;。但你也可以使用 edge_comparator 函数,如下所示:

std::set<Edge, bool(*)(Edge&,Edge&)> edge_set(edge_comparator);

其次,std::sort 只能用于随机访问迭代器或更好的迭代器,而std::set 迭代器是双向的。

【讨论】:

  • 我看到在将对象添加到集合时应该对其进行排序。我更新了问题,你能重新看看吗?
  • @Volkanİlbeyli:你完全改变了问题。不要这样做,它会使答案无效。如果您有不同的问题,请发表不同的帖子。
猜你喜欢
  • 2018-04-08
  • 2011-06-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-03
  • 2017-10-30
  • 2021-12-29
  • 2019-08-30
相关资源
最近更新 更多