矢量擦除错误c2664

vector .erase error c2664

本文关键字:c2664 错误 擦除      更新时间:2023-10-16

我试图迭代一个向量并从中删除特定的项。我从向量的末尾开始工作,这样我就不会在删除项时弄乱迭代器,但当我试图编译时,它会抛出一个错误。我浏览了其他一些有同样错误的帖子,但没有发现任何适用于我的情况的内容,或者如果有,我没有发现,我对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;
} 

任何帮助都将是伟大的

代码中最直接的问题是:

  • 通过传递向量,因此不会修改原始向量
  • 未正确使用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 

我强烈建议您花几天时间处理迭代器。从简单的事情开始(比如这个例子)。

我正在尝试迭代一个向量,并从中删除特定的项目。我从向量的末尾向下工作,这样我就不会在删除项目时弄乱迭代器,

除了通过引用而不是通过值传递之外,不要编写循环和担心迭代器无效,还要学会使用算法,更具体地说,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()的返回值是指向移动项的开头的迭代器。然后,擦除()获取这些项并将它们从向量中删除。

这样做的好处有很多,但其中之一是您不再需要担心"弄乱迭代器"。这很难搞砸——搞砸的一种方法是要么你提供了错误的迭代器类型(然后你会得到语法错误),要么你的比较函数不起作用(很容易修复)。但在运行时,使用无效迭代器的可能性很小甚至没有。

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

1) 必须读几遍才能了解发生了什么和

2) 必须在调试器下运行它,看看它是否做了我认为它做的事情,并且做得正确。

有了算法,我马上就知道代码的作用,更重要的是,代码可以在不需要在调试器下运行的情况下运行。

请注意,我提供的示例使用了一个简单的函数IsGreater()。编写测试函数的其他方法是使用std::greater<>(以及std::bind1st),使用函数对象,使用lambda等。但我提供了可能是最初了解发生了什么的最简单方法。

您正在将向量的副本传递给vectorErase,因此它对副本所做的任何更改都不会对原始向量产生影响。

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

(您通过引用传递iterat,这是您不需要的。您只是把&放错了地方吗?)

有一些问题。首先,必须通过引用传递向量才能影响原始向量。

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