将equal_range与bind2nd和binary_function结合使用

时间:2010-02-25 02:27:39

标签: c++ stl

我有一个已排序的

集合
class Thing
{
public:
   item a;
   item b;
   other data;
};

vector<Thing> Things;

使用

class MultiValuedComparator
{
public:
   item a;
   item b;

   MultiValuedComparator(item c, item d)
   {
      a = c;
      b = d;
   }
};

由于我有项目a和项目b(但不包括其他数据)的重复项,我想获取一些与项目和项目b匹配的数据结构。该集合仅按项目a排序。

我认为equal_range是一种合适的方法。因为我需要匹配从binary_function继承的多个项目。

struct RangeByA : public std::binary_function<Thing, MultiValuedComparator>
{
   bool operator()(const Thing &left, const MultiValuedComparator &right)
   {
      return left.a == right.a && left.b == right.b;
   }
}

我不知道如何编写equal_range函数,所以它会这样做。我试过了:

void somefunction()
{
   typedef pair<vector<Thing>::iterator, 
                vector<Thing>::iterator> startEndIterPair;

   MultiValuedComparator mvc(1, 2);

   startEndIterPair p = equal_range
      (
      Things.start(), 
      Things.end(), 
      std::bind2nd(RangeByA, mvc)
      );
}

但是这段代码抱怨'运营商&lt;'不匹配在'__middle .__ gnu_cxx :: __ normal_iterator ..等调用equal_range

我如何写这个,所以equal_range会起作用?我不知道在哪里放置重载运算符。 RangeByA似乎不接受它。

1 个答案:

答案 0 :(得分:0)

equ_range的比较器的要求是严格的弱排序(不相等)。此外,必须能够使用两个命令中的参数调用比较器:

comparator(*iter, value); // items less than lower bound
comparator(value, *iter); // items greater than upper bound

然后,equal_range的结果是迭代器的范围,其中这两个调用都返回false

然后,一个简单的调整是向MultiValuedComparator添加一个接受Thing的构造函数,允许将Thing对象转换为MultiValuedComparator对象进行比较:

class MultiValuedComparator
{
public:
   item a;
   item b;

   MultiValuedComparator(item c, item d)
   {
      a = c;
      b = d;
   }

   MultiValuedComparator(const Thing &thing)
   {
      a = thing.a
      b = thing.b
   }
};

然后将比较器调整为仅使用MultiValuedComparator并使用严格的弱排序:

struct RangeByA : public std::binary_function<MultiValuedComparator, MultiValuedComparator>
{
   bool operator()(const MultiValuedComparator &left, const MultiValuedComparator &right)
   {
      // Sorted by a first, then b if necessary
      return (left.a < right.a)
              || (!(right.a < left.a) && (left.b < right.b)));
   }
};

上面的替代方法,它将避免副本(从Thing到MultiValuedComparator),只是在两个方向上实现operator()(Thing vs. MultiValuedComparator和MultiValuedComparator vs. Thing),删除{{1}的继承。 1}}(这里不需要):

std::binary_function