首页 文章

std :: remove_if中的const参数

提问于
浏览
7

我要删除 list of pairs 中的元素 . 当我使用一对像

std::pair<const int, bool>

我收到以下编译错误:

在/ usr / local / include / c /6.1.0/utility:70:0中包含的文件中,来自/ usr / local / include / c /6.1.0/algorithm:60,来自main.cpp:1:/ usr / local / include / c /6.1.0/bits/stl_pair.h:实例化'std :: pair <_T1,_T2>&std :: pair <_T1,_T2> :: operator =(std :: pair) <_T1,_T2> &&)[with _T1 = const int; _T2 = bool]':/ usr / local / include / c /6.1.0/bits/stl_algo.h:868:16:需要'_ForwardIterator std :: __ remove_if(_ForwardIterator,_ForwardIterator,_Predicate)[with _ForwardIterator = std: :_List_iterator> _Predicate = __gnu_cxx :: __ ops :: _ Iter_pred&)>>]'/ usr / local / include / c /6.1.0/bits/stl_algo.h:936:30:需要'_FIter std :: remove_if(_FIter) ,FIter,Predicate)[与_FIter = std :: _ List_iterator> _Predicate = main()::&)>]'main.cpp:17:32:从这里需要/ usr / local / include / c /6.1.0/ bits / stl_pair.h:319:8:错误:只读成员的分配'std :: pair :: first'first = std :: forward( p.first);

这是示例代码:

int main()
{
    int id = 2;

    std::list< std::pair <const int, bool> >  l;
    l.push_back(std::make_pair(3,true));
    l.push_back(std::make_pair(2,false));
    l.push_back(std::make_pair(1,true));

    l.erase(std::remove_if(l.begin(), l.end(), 
        [id](std::pair<const int, bool>& e) -> bool {
        return e.first == id; }));

    for (auto i: l) {
        std::cout << i.first << " " << i.second << std::endl;
    }
}

我知道(如果我错了,请纠正我):

  • 只要列表的任何元素中都有constness,我就会遇到完全相同的问题,例如, list <const int> 也会返回编译错误 .

  • 如果我删除对中第一个元素中的const,代码将起作用 .

  • 更优雅高效的方法是使用remove_if list方法,如下所示:

l.remove_if([id](std::pair<const int, bool>& e) -> bool {
    return e.first == id; });

但我的问题是,std :: remove_if的内部工作原理是什么,它强加了容器的元素不是const?

2 回答

  • 4

    如果查看std::remove_if的类型和迭代器要求,可以看到实现必须类似于以下内容(来自上面的链接):

    template<class ForwardIt, class UnaryPredicate>
    ForwardIt remove_if(ForwardIt first, ForwardIt last, UnaryPredicate p)
    {
        first = std::find_if(first, last, p);
        if (first != last)
            for(ForwardIt i = first; ++i != last; )
                if (!p(*i))
                    *first++ = std::move(*i);
        return first;
    }
    

    即,该算法仅假设迭代器具有前向能力,并且元素是可移动的,并且它周围的元素是 move . 当然, move s无法在 const 对象上完成 .

  • 5

    一般std::remove_if shuffles项目值将逻辑擦除的值放在序列的末尾(它通常与成员函数erase组合使用以实际删除逻辑上擦除的值) . 它可以复制或移动 . 而是使用std::list::remove_if .

相关问题