1

我想尽可能避免代码重复。假设我有一个类,例如,

class T {
    int val;
    bool operator < (const T& right) const { return val < right.val; }
}

我希望能够像这样调用 std::sort() ,

std::sort( SomeContainer.begin(), SomeContainer.end(), FuncAdaptedFromOp );

这是我在 StackOverflow 上的第一个问题。请原谅。

编辑

问题是该类可能具有多个bool T::Compare (const T& right)功能。我仍然想要一个适配器。举这个例子,

class Edge {
    Vertex u, v;
    bool CompareSrc (const Edge& right) const { return u < right.u; }
    bool CompareDest (const Edge& right) const { return v < right.v; }
}

有时我想按 sourceVertex有时按 destination排序Vertex。我只是想知道这是否可能。

4

3 回答 3

2

如果您不提供第三个参数,则将使用 < 运算符。

http://www.cplusplus.com/reference/algorithm/sort/

“第一个版本使用 operator< 比较元素,第二个版本使用 comp。”

于 2012-04-07T07:15:03.140 回答
1

您只需复制 STL 仿函数std::less http://www.cplusplus.com/reference/std/functional/less/

template <class T> struct less : binary_function <T,T,bool> {
  bool operator() (const T& x, const T& y) const
    {return x<y;}
};

少的例子:

#include <iostream>
#include <functional>
#include <algorithm>

struct my_struct {
   int a;
   bool operator< (const my_struct &s) const {
      return a < s.a;
   }
};

int main() {
   my_struct array[10];

   for (int i = 0; i < 10; ++i)
      array[i].a = 10 - i;

   std::sort(array, array + 10, std::less<my_struct>());

   for (int i = 0; i < 10; ++i)
      std::cout << array[i].a << ", ";
}

你不需要写它。算法std::sort有两个版本:

template <class RandomAccessIterator>
  void sort ( RandomAccessIterator first, RandomAccessIterator last );

template <class RandomAccessIterator, class Compare>
  void sort ( RandomAccessIterator first, RandomAccessIterator last, Compare comp );

operator <当您的课程提供(可比较)时,可以使用第一个版本。如果您不想使用operator <或它不存在,则使用第二个版本。

没有更少的例子:

#include <iostream>
#include <functional>
#include <algorithm>

struct my_struct {
   int a;
   bool operator< (const my_struct &s) const {
      return a < s.a;
   }
};

int main() {
   my_struct array[10];

   for (int i = 0; i < 10; ++i)
      array[i].a = 10 - i;

   std::sort(array, array + 10);

   for (int i = 0; i < 10; ++i)
      std::cout << array[i].a << ", ";
}

示例具有相同的结果。

您还可以使用其他仿函数来更改排序算法的行为,例如std::greater.

于 2012-04-07T07:20:42.040 回答
1
using namespace std::placeholders;
std::sort(SomeContainer.begin(), SomeContainer.end()
    // or use &Edge::CompareDest if you want that instead
    , std::bind(&Edge::CompareSrc, _1, _2) );

std::bind虽然是 C++11,所以你可能想要使用boost::bind(在这种情况下你不应该使用前面的 using 指令)或bind来自 TR1 的,如果你的实现有的话。否则,我建议您手动处理自己的仿函数。

于 2012-04-07T08:17:49.963 回答