首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >矢量.erase误差c2664

矢量.erase误差c2664
EN

Stack Overflow用户
提问于 2014-04-11 19:07:51
回答 4查看 780关注 0票数 0

我正在尝试迭代一个向量并从它中删除特定的项目。我正在从向量的末尾开始工作,这样我就不会在条目被移除时搞乱迭代器,但是当我试图编译时,它会抛出一个错误。我查看了其他一些带有相同错误的帖子,但没有看到任何适用于我的情况,或者如果没有发现,我仍然对C++和一般编程非常陌生。下面是一个简单的代码示例来说明我的问题。

代码语言:javascript
复制
#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;
} 

任何帮助都是很好的

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2014-04-11 21:24:03

代码中最直接的问题是:

  • 通过值传递向量,这样原始的就不会被修改。
  • 没有正确地使用erase()。它将一个迭代器返回到序列中的下一个元素,您还没有擦除(现在)。这意味着,如果使用迭代器并删除元素,则不需要(也不应该)增加迭代器。一个例子即将出现。
  • 与上面的内容结合起来,简单地说,您没有使用迭代器,您应该使用迭代器。

您的代码可以不使用该函数,只需这样做:

代码语言:javascript
复制
#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;
}

输出

代码语言:javascript
复制
0 1 2 3 4 5 6 7 8 9 10 
0 1 2 3 4 5 6 

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

票数 2
EN

Stack Overflow用户

发布于 2014-04-11 19:25:30

我正在尝试迭代一个向量并从它中删除特定的项目。我从向量的末尾开始工作,这样我就不会在项目被移除的时候搞乱迭代器,

除了通过引用而不是通过值传递,而不是编写循环和担心迭代器无效之外,学习如何使用算法,更具体地说,用于容器(如向量)的erase/remove_if成语。即使是优秀的C++程序员也很容易出错,这就是应该使用算法的原因。

下面是一个使用该成语的示例(擦除/删除_if)。

代码语言:javascript
复制
#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++程序员都可以立即了解擦除/删除_if()的功能。如果我看了你的代码而你没告诉我们它做了什么,我会

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

2)必须在调试器下运行它,以查看它是否执行了我认为的操作,并正确地执行了它。

有了算法,我马上就知道代码是干什么的,更重要的是,代码不用在调试器下运行。

注意,我提供的示例使用了一个简单的函数IsGreater()。编写测试函数的其他方法是使用std::greater<> (连同std::using 1)、使用函数对象、使用lambda等等。但是,我提供了一种最简单的方法来初步了解正在发生的事情。

票数 1
EN

Stack Overflow用户

发布于 2014-04-11 19:15:19

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

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

(您正在通过引用传递iterat,这是您不需要的。你刚才是不是把&放错地方了?)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23020726

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档