C++ C++;11 STL唯一功能,但相反

C++ C++;11 STL唯一功能,但相反,c++,iterator,unique,predicate,deque,C++,Iterator,Unique,Predicate,Deque,是否有一个函数的操作方式类似于std::unique,但它接受一个自定义比较谓词,并以等效顺序保留最后一个元素,而不是第一个元素?如果选择C++14或C++17,答案是肯定的;但是我使用的是C++11 我从一组大而重的对象开始,按一个轻量级字段排序。对于轻量级字段,某些对象的值相等,这是不可接受的。我需要丢弃任何序列中具有匹配光场的所有对象,但最后一个对象除外 目前,我的代码使用自定义二进制谓词和helper重载对象调用equal_range,然后倒带结束迭代器: deque<Heavy&

是否有一个函数的操作方式类似于
std::unique
,但它接受一个自定义比较谓词,并以等效顺序保留最后一个元素,而不是第一个元素?如果选择C++14或C++17,答案是肯定的;但是我使用的是C++11

我从一组大而重的对象开始,按一个轻量级字段排序。对于轻量级字段,某些对象的值相等,这是不可接受的。我需要丢弃任何序列中具有匹配光场的所有对象,但最后一个对象除外

目前,我的代码使用自定义二进制谓词和helper重载对象调用
equal_range
,然后倒带结束迭代器:

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);

请注意,我想象的神奇函数采用一元谓词,而不是二元谓词

大概是这样的吧

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)};
}

此处
reverse\u迭代器::base()
返回
unique()
返回的
reverse\u迭代器的底层原始迭代器。当
unique()
返回序列的新结尾时,反向操作返回序列的新开始。新范围是
{new\u begin,orignal\u end}
,范围
{original\u begin,new\u begin}
中的元素必须是
erase()
d.

使用反向迭代器?如果我理解正确,您想从超集获取,超集中找到的最后一个元素?@KillzoneKid,似乎我的编译器和cplusplus.com都告诉我std::unique只接受转发器迭代器。@ChristopherPisz是的,这是正确的总结。我想用最小的复制/移动操作来执行此操作,因为对象很重。@KevinHencke我想你弄错了我喜欢你第二个建议的外观,但得到了以下错误消息:错误:没有合适的用户定义的从“std::reverse_iterator”到“const std::_Deque_iterator”的转换我正在尝试你的第一个建议;如果没有匹配,该解决方案会失败吗?我们是否会以&*return.second<&*return.first结束,因为他们会互相寻找end()和rend()?@KevinHencke指的是
unique()
反向迭代器的用法:在解释我的答案中返回的迭代器(
reduced
)时需要小心。它显然是一个
反向迭代器
,因此不会自动转换为原始迭代器类型,但为此,您可以使用
base()
。我要修改我的答案。
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)};
}
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());