矢量擦除错误c2664
vector .erase error c2664
我试图迭代一个向量并从中删除特定的项。我从向量的末尾开始工作,这样我就不会在删除项时弄乱迭代器,但当我试图编译时,它会抛出一个错误。我浏览了其他一些有同样错误的帖子,但没有发现任何适用于我的情况的内容,或者如果有,我没有发现,我对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;
}
- 为什么这个错误变成(C2664错误C ++ Visual Studio)
- 编译方面的问题.错误E0413、E0434、C2664、C2440
- 使用解算器SparseLU并获得错误C2664
- std::映射导致插入时出现C2664错误
- VS 2017 错误 C2664 地图插入尝试
- 使用自定义对象声明shared_ptr数组时出现错误 C2664
- 编译器错误 C2664 使用 std::map 和自定义类作为其值
- 如何在 VC++ 中通过引用传递另一个对象的方法(错误 C2664)
- C2664 :当我使用 str.append(str[i]) 时,发生错误
- 在C++中构造模板函数时出现编译错误 C2664 和 C2440
- 了解错误 C2664:无法转换参数 1
- 错误 C2664:无法从'NvPhysicalGpuHandle'转换参数 1
- 错误 C2664 和 E0167 被难倒
- 尝试创建unique_ptr时出现错误 C2664
- E0312,C2664尝试将向量对象作为函数参数传递时错误
- 错误 C2664:"errno_t wcstombs_s(size_t *,字符 *,size_t,常量 wchar_t *,size_t)":无法转换参数 4
- 错误C2664:无法转换参数错误
- 在集合中转换为小写 C++ 错误 C2664
- C2664错误,C++,这对我来说是外来的
- vector迭代的派生和基之间的类型转换:C2664错误