C++11 STL 独有的函数,但反过来
C++11 STL unique function, but in reverse
是否有像 std::unique
一样运行的函数,但它采用自定义比较谓词,并在等效序列中保留 last 元素,而不是第一个?如果可以选择 C++14 或 C++17,答案是肯定的;但是我正在使用 C++11.
我从一个大型重对象的双端队列开始,按一个轻量级字段排序。某些对象对于轻量级字段具有相同的值,这是不可接受的。我需要在具有匹配光场的任何序列中丢弃除 last 对象之外的所有对象。
目前我的代码调用 equal_range
使用自定义 binary 谓词和辅助重对象,然后倒回结束迭代器:
deque<Heavy> heavyDeque(...);
Light helperLight(...);
Heavy helperHeavy(helperLight, );
typedef deque<Heavy>:: iterator HevIt;
pair<HevIt, HevIt> deleteRange = equal_range(
heavyDeque.begin(), heavyDeque.end(), helperHeavy,
[](const Heavy & lhs, const Heavy & rhs) {
return lhs.getLight() < rhs.getLight()})
//I have prior knowledge of at least one match
assert(deleteRange.first != deleteRange.second);
// back up; don't delete the last one
--(deleteRange.second);
heavyDeque.erase(deleteRange.first, deleteRange.second);
我对必须传入 helperHeavy
不太满意,因为我只需要 helperLight
。我希望我的代码看起来像这样:
pair<HevIt, HevIt> deleteRange = magical_range_search(
heavyDeque.begin(), heavyDeque.end(),
[helperLight](const Heavy & heavy) {
return helperLight == heavy.getLight()})
请注意,我虚构的魔法函数采用 一元 谓词,而不是二元谓词。
也许是这样的?
template<typename BidirectionalIterator, typename UnaryPredicate>
pair<BidirectionalIterator,BidirectionalIterator>
magical_range_search(BidirectionalIterator begin,
BidirectionalIterator end, UnaryPredicate p)
{
return {find_if(begin,end,p),
find_if(make_reverse_iterator(end),make_reverse_iterator(begin),p)};
}
但是,当然,您可以将 std::unique
与 reverse_iterator
一起使用,如评论中所示:
heavyContainer.erase(heavyContainer.begin(),
unique(make_reverse_iterator(heavyContainer.end()),
make_reverse_iterator(heavyContainer.begin()),
[](Heavy const&lhs, Heavy const&rhs) {
return lhs.getLight() < rhs.getLight();
}).base());
这里reverse_iterator<>::base()
returns是unique()
返回的reverse_iterator
的底层原始迭代器。如unique()
returns新序列的结束,反向操作returns新序列的开始。新范围为{new_begin, orignal_end}
,{original_begin, new_begin}
范围内的元素必须为erase()
d.
是否有像 std::unique
一样运行的函数,但它采用自定义比较谓词,并在等效序列中保留 last 元素,而不是第一个?如果可以选择 C++14 或 C++17,答案是肯定的;但是我正在使用 C++11.
我从一个大型重对象的双端队列开始,按一个轻量级字段排序。某些对象对于轻量级字段具有相同的值,这是不可接受的。我需要在具有匹配光场的任何序列中丢弃除 last 对象之外的所有对象。
目前我的代码调用 equal_range
使用自定义 binary 谓词和辅助重对象,然后倒回结束迭代器:
deque<Heavy> heavyDeque(...);
Light helperLight(...);
Heavy helperHeavy(helperLight, );
typedef deque<Heavy>:: iterator HevIt;
pair<HevIt, HevIt> deleteRange = equal_range(
heavyDeque.begin(), heavyDeque.end(), helperHeavy,
[](const Heavy & lhs, const Heavy & rhs) {
return lhs.getLight() < rhs.getLight()})
//I have prior knowledge of at least one match
assert(deleteRange.first != deleteRange.second);
// back up; don't delete the last one
--(deleteRange.second);
heavyDeque.erase(deleteRange.first, deleteRange.second);
我对必须传入 helperHeavy
不太满意,因为我只需要 helperLight
。我希望我的代码看起来像这样:
pair<HevIt, HevIt> deleteRange = magical_range_search(
heavyDeque.begin(), heavyDeque.end(),
[helperLight](const Heavy & heavy) {
return helperLight == heavy.getLight()})
请注意,我虚构的魔法函数采用 一元 谓词,而不是二元谓词。
也许是这样的?
template<typename BidirectionalIterator, typename UnaryPredicate>
pair<BidirectionalIterator,BidirectionalIterator>
magical_range_search(BidirectionalIterator begin,
BidirectionalIterator end, UnaryPredicate p)
{
return {find_if(begin,end,p),
find_if(make_reverse_iterator(end),make_reverse_iterator(begin),p)};
}
但是,当然,您可以将 std::unique
与 reverse_iterator
一起使用,如评论中所示:
heavyContainer.erase(heavyContainer.begin(),
unique(make_reverse_iterator(heavyContainer.end()),
make_reverse_iterator(heavyContainer.begin()),
[](Heavy const&lhs, Heavy const&rhs) {
return lhs.getLight() < rhs.getLight();
}).base());
这里reverse_iterator<>::base()
returns是unique()
返回的reverse_iterator
的底层原始迭代器。如unique()
returns新序列的结束,反向操作returns新序列的开始。新范围为{new_begin, orignal_end}
,{original_begin, new_begin}
范围内的元素必须为erase()
d.