0

我有一个看起来像这样的场景:

#include <algorithm>
using namespace std;

// a "heavy" struct with lots of members
struct B {
  int key;
  // other members  
} 

class A {
  vector<B> bs;
}

我想按他们的键对 bs 进行排序。现在,我过去为避免交换 B(因为它们相当重)而这样做的一种方法是定义一个索引向量并对索引进行排序。如果 bs 不是类成员,则此方法有效。

例如

vector<B> bs;
vector<size_t> indices;

bool pred(size_t i, size_t j) { return bs[i] < bs[j]; }

indices.resize(bs.size());
for (size_t i = 0; i < bs.size(); i++) indices[i] = i;
std::sort(indices.begin(), indices.end(), pred);

但是,当 bs 是类成员时,这种“技术”会失败,因为谓词只能带两个参数。特别是,没有办法传递“this”。

我可以看到解决此问题的三种不同方法:

  • 不要为指数烦恼。只是重载运算符<来处理 B 的实例。整个索引的事情只是过早的优化:-)
  • 有一个指向 的全局指针bs,在调用之前设置它sort,然后在pred.
  • 使用闭包。这会很酷,除非我没有使用 C++11。

有没有其他方法可以做到这一点?谢谢!

4

2 回答 2

1

如果您可以为其编写轻量级交换,B那么问题并不存在:sort将使用您的轻量级交换。

如果这不是一个选项,您可以将指向您的类的(智能)指针存储在向量中并对指针进行排序。

或者让你的班级使用 pimpl 成语然后交换,因为几乎免费。

绝对不要使用全局指针,因为有时有人想让这段代码线程安全,而用于排序的全局容器将成为任何尝试对这些对象进行多线程排序的巨大刺。

于 2012-06-27T05:08:58.593 回答
1

假设它b位于class A并且可以通过一个名为 的成员函数访问get,您可以编写如下仿函数:

struct Comparator
{
  Compartor(A& a): m_a(a){}
  bool operator()(int i, int j) const
  {
    return m_a.get(i) < m_a.get(j);
  }

 A& m_a;
};

并像这样使用它:

A a;
std::sort(indices.begin(), indices.end(), Comparator(a));
于 2012-06-27T05:10:04.807 回答