将 equal_range 与bind2nd 和binary_function 结合起来
的排序集合,
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 的重复项(但没有其他数据),所以我想获取与项目 a 和项目 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)
);
}
但是这段代码抱怨“operator<”不匹配在 '__middle.__gnu_cxx::__normal_iterator .. 等中调用 equal_range 时,
我该如何编写这个以便 equal_range 起作用?我不知道在哪里放置重载运算符。 RangeByA似乎不接受它。
I have a sorted collection of
class Thing
{
public:
item a;
item b;
other data;
};
vector<Thing> Things;
using
class MultiValuedComparator
{
public:
item a;
item b;
MultiValuedComparator(item c, item d)
{
a = c;
b = d;
}
};
Since I have duplicates of item a, and item b (but not other data), I want to grab a range of those data structures that match item a AND item b. The collection is sorted by item a only.
I thought equal_range would be an appropriate method to do this. Since I needed to match more than one item I inherited from 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;
}
}
I don't know how to write the equal_range function so it does this. I tried:
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)
);
}
but this code complains of no match for 'operator<' in '__middle.__gnu_cxx::__normal_iterator .. etc at the call to equal_range
How do I write this so equal_range will work? I have no idea where to place the overloaded operator. RangeByA does not seem to accept it.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
equal_range 比较器的要求是严格的弱排序(而不是相等)。此外,比较器必须能够使用两种顺序的参数进行调用:
equal_range 的结果就是这两个调用都返回 false 的迭代器范围。
那么,一个简单的调整就是向您的 MultiValuedComparator 添加一个接受 Thing 的构造函数,允许将 Thing 对象转换为 MultiValuedComparator 对象以进行比较:
然后调整您的比较器以仅使用 MultiValuedComparator 并使用严格的弱排序:
上述方法的另一种替代方案可以避免复制(从 Thing 到 MultiValuedComparator),即简单地在两个方向(Thing 与 MultiValuedComparator 以及 MultiValuedComparator 与 Thing)实现
operator()
,从而放弃继承std::binary_function
(此处不需要):The requirement of a comparator for equal_range is a strict weak ordering (not equality). In addition, the comparator must be able to be called with the arguments in both orders:
The result of equal_range, then, is the range of iterators where both of these calls return
false
.A simple adjustment, then, is to add a constructor to your MultiValuedComparator that accepts a Thing, allowing a Thing object to be converted to a MultiValuedComparator object for comparison:
And then adjust your comparator to only use MultiValuedComparator and to use a strict weak ordering:
An alternative to the above, which will avoid copies (from Thing to MultiValuedComparator), is to simply implement
operator()
in both directions (Thing vs. MultiValuedComparator and MultiValuedComparator vs. Thing), dropping the inheritance ofstd::binary_function
(not needed here):