c.erase(p)无法编译成功,为什么?

时间:2009-09-09 07:49:26

标签: c++

我曾尝试在列表中测试擦除功能,但我无法成功!我的编译器的错误消息是:

[Error]error: no matching function for call to
`std::list<int,std::allocator<int> >::erase(std::_List_const_iterator<int>&)'.

我的代码如下:

#include <iostream>
#include <list>
using namespace std;

int main()
{
    int ia[] = {0, 1, 1, 2, 3, 5, 8, 13, 21, 55, 89};
    list<int> ilst(ia, ia + 11);

    list<int>::const_iterator iter2 = ilst.begin();
    for(; iter2 != ilst.end(); ++iter2)
    {
        if(*iter2 % 2 != 0)
        {   
            iter2 = ilst.erase(iter2);  //error!
            --iter2;
        }
    }
    iter2 = ilst.begin();   
    for(; iter2 != ilst.end(); ++iter2)
    {
        cout << *iter << " ";
    }   
    cout << endl;
}

感谢您的导游!

3 个答案:

答案 0 :(得分:6)

看看这个示例,我认为你可以毫无困难地转移到list :: iterator而不是list :: const_iterator。 这样编译的代码没有错误

答案 1 :(得分:1)

代码实际上闻起来很糟糕。应该有可能在擦除之后iter2引用列表的开头(如果你碰巧删除了第一个项目),在这种情况下你不应该减少它。

循环中正确的擦除形式如下所示:

for(list<int>::iterator iter2 = ilst.begin(); iter2 != ilst.end(); )
{
    if(*iter2 % 2 != 0)
    {       
        iter2 = ilst.erase(iter2);      //no error, if not using const_iterator
    }
    else {
        ++iter2; //only increment if didn't erase
    }
}

我还建议像TimW一样使用remove_if,除非有人应该使用成员函数而不是自由函数(如std :: list的情况),我认为compose1不在标准库中(但是? )。关于第二点,幸运的是在这种情况下,它不需要那么复杂:

ilst.remove_if(bind2nd(modulus<int>(), 2));

答案 2 :(得分:0)

您也可以使用:

list<int>::iterator new_end = 
        remove_if(ilst.begin(), ilst.end(), 
                  compose1(bind2nd(equal_to<int>(), 0),
                           bind2nd(modulus<int>(), 2)));
ilst.erase(new_end, ilst.end());
copy(ilst.begin(), ilst.end(), ostream_iterator<int>(cout, " "));