vector .erase error c2664

时间:2014-04-11 19:07:52

标签: c++ vector compiler-errors

我正在尝试迭代向量并从中删除特定项目。我正在向下生成向量的末尾,以便在删除项目时不会弄乱迭代器,但是当我尝试编译它时会抛出错误。我查看了一些其他帖子,但同样的错误,但没有看到任何适用于我的情况,或者如果我没有抓住它,我仍然是C ++和编程的新手。下面是一个简单代码的示例,用于说明我的问题。

#include <iostream>
#include <vector>

using namespace std;

int vectorErase(vector<int>, int &);

int main()
{
    vector<int> test;

    for(int i=0; i<11;i++)
    {
        test.push_back(i);
        cout<<test[i];
    }

    for(int i=10;i<=0;i--)
    {
        vectorErase(test, i);
        cout<<test[i];
    }

    system("pause");
    return 0;
}

int vectorErase(vector<int> test, int &iterat)
{
    if(test[iterat]>6)
    {
        test.erase(iterat);
    }
    return 0;
} 

任何帮助都会很棒

4 个答案:

答案 0 :(得分:2)

代码中最直接的问题是:

  • 通过传递矢量,因此原件永远不会被修改。
  • 未正确使用erase()。它返回一个迭代器到序列中的 next 元素,你做了 not erase(还)。这意味着如果使用迭代器并删除元素,则不需要(也不应该)递增迭代器。一个例子即将到来。
  • 与上述相关,简单地说,你没有使用迭代器,你应该是。

您的代码可以不使用该功能,只需执行此操作:

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

int main()
{
    vector<int> test;

    for(int i=0; i<11;i++)
    {
        cout << i << ' ';
        test.push_back(i);
    }
    cout << '\n';

    for(auto it = test.begin(); it != test.end();)
    {
        if (*it > 6)
            it = test.erase(it);
        else
        {
            cout << *it << ' ';
            ++it;
        }
    }
    cout << '\n';

    return 0;
}

<强>输出

0 1 2 3 4 5 6 7 8 9 10 
0 1 2 3 4 5 6 

我强烈建议您花几天时间使用迭代器。从简单的东西开始(比如这个例子)。

答案 1 :(得分:1)

  

我正在尝试迭代向量并从中删除特定项目。我在向量的末尾工作,以便在删除项目时不会弄乱迭代器,

除了通过引用而不是通过值传递,而不是编写循环并担心使迭代器无效,学习使用算法,更具体地说是容器(如vector)的erase/remove_if惯用法。即使是优秀的C ++程序员也很容易犯错,这就是为什么应该使用算法的原因。

以下是使用成语(erase / remove_if)的示例。

#include <algorithm>
//...
bool IsGreater(int val) { return val > 6; }
//...
test.erase(std::remove_if(test.begin(), test.end(), IsGreater), test.end());

remove_if接受满足条件的项目并将它们移动到向量的末尾。 remove_if()的返回值是指向移动项的开头的迭代器。然后erase()获取项目并从向量中删除它们。

以这种方式做事的好处很多,但其中一个就是你不再需要担心“弄乱迭代器”。很难弄清楚这一点 - 弄乱的一种方法是你提供错误的迭代器类型(然后你会得到一个语法错误),或者你的比较函数不起作用(很容易修复)。但是在运行时,几乎没有机会使用无效的迭代器。

另一个优点是任何优秀的C ++程序员都可以立即理解erase / remove_if()的作用。如果我查看你的代码并且你从未告诉我们它做了什么,我会

1)必须阅读几次才能了解正在发生的事情

2)必须在调试器下运行它以查看它是否符合我的想法,并且正确执行。

使用这些算法,我立刻知道代码的作用,更重要的是,代码无需在调试器下运行即可运行。

请注意,我提供的示例使用了一个简单的函数IsGreater()。编写测试函数的其他方法是使用std :: greater&lt;&gt; (以及std :: bind1st),使用函数对象,使用lambda等。但我提供了最简单的方法来初步了解正在发生的事情。

答案 2 :(得分:0)

您已将矢量副本传递给vectorErase,因此对其副本所做的任何更改都不会影响原件。

如果要修改传递给函数的向量,则需要引用原始对象而不是副本。这很容易 - 而不是vector<int> test,请写vector<int> & test

(您正在通过引用传递iterat,这是您不需要的。您刚刚将&放在错误的位置吗?)

答案 3 :(得分:0)

有一些问题。首先,事实是你必须通过引用传递向量来影响原始。

int vectorErase(vector<int>&, int );

然后是第二个循环的问题:

    for(int i=10;i>=0;i--)
    {
        vectorErase(test, i);
        cout<<test[i] << ' ';
    }

最后,函数本身正确使用erase

int vectorErase(vector<int> &test, int iterat)
{
    if(test[iterat]>6)
    {
        test.erase(test.begin()+iterat);
    }
    return 0;
}