C ++ 11 STL独有的功能,但反过来

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C ++ 11 STL独有的功能,但反过来相关的知识,希望对你有一定的参考价值。

是否有一个像std::unique一样运行的函数,但它采用自定义比较谓词,并保留等效序列中的最后一个元素,而不是第一个?如果C ++ 14或C ++ 17是一个选项,答案是肯定的;但是我使用的是C ++ 11。

我开始使用一个大型重物的副本,按一个轻量级场分类。某些对象具有相同的轻量级字段值,这是不可接受的。我需要丢弃除了匹配光场的任何序列中的最后一个对象以外的所有对象。

目前我的代码使用自定义二元谓词和辅助重量对象调用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);

我不太高兴必须通过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::uniquereverse_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()返回由reverse_iterator返回的unique()的基础原始迭代器。当unique()返回序列的新结尾时,反向操作返回序列的新开始。新的范围是{new_begin, orignal_end}{original_begin, new_begin}范围内的元素必须是erase()d。

以上是关于C ++ 11 STL独有的功能,但反过来的主要内容,如果未能解决你的问题,请参考以下文章

在Scala项目中使用Spring Cloud

在Qt编程中,如何调用C++的STL?

swig c++ to perl : 如何使用 c++11 字符串 STL 函数

C++ STL应用与实现5: 如何使用std::array (since C++11)

C++ STL 基础及应用 模板与操作符重载

C++ STL应用与实现23: 如何使用std::mem_fn (since C++11)