std::sort 具有多个属性的相等对象

std::sort equal objects with multiple properties

我正在尝试对对象向量进行排序,使具有相同属性的对象彼此相邻。 Task 是一个 class,它接受并保存 3 个指向某处数据的指针。

vec.push_back(Task(&propertyOne, &propertyTwo, &propertyThree));

如果我有一个充满这些的向量,我想对它们进行排序,以便放置任何 propertyOnepropertyTwopropertyThree 相等的 Task在向量中彼此相邻。如果两个 Task 对象属性不相等,那么它们去哪里并不重要。尽管他们最好靠近他们最共同的 Task 个对象。

我该怎么做?我已经尝试了明显的 (return a.propertyOne == b.propertyOne) 但它似乎根本不起作用,而且它只比较了第一个 属性.

让我们的任务有三个属性,简称a、b、c。要以正确的顺序对此类任务进行排序,您必须执行以下操作:

std::sort(v.begin(), v.end(), [](const Task& l, const Task& r) {
  if (l.a == r.a) {
    if (l.b == r.b) {
      return l.c < r.c;
    }
    return l.b < r.b;
  }
  return l.a < r.a;
});

最佳解决方案是使用 tuple<property*, property*, property*> not a Task. This comes with comparison operators 定义,这样您就可以简单地执行:vec.push_back(make_tuple(&propertyOne, &propertyTwo, &propertyThree))vec 中的每个条目进行排序,然后只需执行:

sort(vec.begin(), vec.end())

如果 Task 必须比 tuple<property*, property*, property*> 更详细,您应该为 Task 定义比较运算符:

bool Task::operator< (const Task& rhs) {
    return make_tuple(a, b, c) < make_tuple(rhs.a, rhs.b, rhs.c);
}

bool Task::operator== (const Task& rhs) {
    return a == rhs.a && b == rhs.b && c == rhs.c;
}

一旦定义了这两个,您就可以再次执行:

sort(vec.begin(), vec.end())

我会使用包含几个三元运算符的简单 lambda 来实现

std::sort(v.begin(), v.end(), [](const Task& l, const Task& r)
  {
      return (l.a == r.a) ?
          ((l.b == r.b) ? (l.c < r.c) : (l.b < r.b)) :
          (l.a < r.a);
  });

这显然假设属性 ab 可以使用 == 进行比较,并且所有三个属性都可以使用 <.[=18= 进行比较]

或者,您可能希望提供来自 <functional>std::equal_tostd::less 等)的泛函的适当特化,并改用它们。