矢量擦除错误
我在C++下面的代码:矢量擦除错误
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <vector>
int main()
{
srand(time(0));
int noOfElements = 9;
for (int a = 0; a < 9; a++)
{
std::vector<int> poss;
for (int a = 1; a <= 9; a++)
poss.push_back(a);
for (int b = 0; b < 9; b++)
{
int random = rand() % 9;
std::cout << poss[random];
poss.erase(random);
noOfElements--;
}
std::cout << "\n";
}
}
然而,当我运行它,它返回:
error: no matching function for call to 'std::vector<int>::erase(int&)'
线路13
这是为什么和我该如何纠正它?
您无法直接从向量中删除值(向量是序列容器,而不是关联容器):您需要为要删除的元素提供迭代器。
为了得到一个迭代,则可以:
- 发现根据其值的元件(通过使用
std::find()
EG),然后到erase()
成员函数提供在输入端的返回的迭代,或 - 通过将偏移量应用于指向矢量开头的迭代器(即由
begin()
成员函数返回的对象)来获取它。
在第一种情况:
#include <vector>
#include <algorithm>
int main()
{
std::vector<int> v { 1, 2, 3};
auto i = std::find(begin(v), end(v), 2);
v.erase(i);
}
上面的代码使用了一些C++ 11层的功能。在C++ 03,它看起来如下:
#include <vector>
#include <algorithm>
int main()
{
std::vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
std::vector<int>::iterator i = std::find(v.begin(), v.end(), 2);
v.erase(i);
}
在第二种情况下,如果你知道你的元素的矢量(比如说,pos
)内指数,那么你就可以轻松搞定迭代器是这样的:
v.begin() + pos
或者(仅C++ 11),你可以这样做:
next(begin(v), pos);
在这种情况下,我认为他很可能想要'std :: vector
@Chowlett:重新阅读这个问题,看起来你是对的。起初,我认为“随机”是OP想要擦除的*值*,而不是它的位置。但事实可能并非如此,所以我更新了我的答案以涵盖两种情况。谢谢 – 2013-04-25 15:50:11
向量擦除函数采用迭代器不值。 而且您还需要检查边界条件,以查看您正在擦除的索引是否不受限制。
std::vector<int>::iterator itr = poss.begin() + random;
if(itr != poss.end())
{
poss.erase(itr);
}
你所做的边界检查是非常不够的,它会检查迭代器对一个可能的无效值,当然,形成任何迭代器都是未定义的行为因此,如果你真的想做一个边界检查,你应该在整数上完成它,然后将它添加到'poss.begin()'中。当然,如果你完全控制了生成整数,就像这里的情况一样,这就是整数的值应该被绑定的地方:'int random = rand()%poss.size();'。任何额外的检查都是多余的。 – 2013-04-25 16:37:31
http://en.cppreference.com/w/cpp/container/vector/erase – hmjd 2013-04-25 15:39:34
你试图抹掉随机位置,或者随机值?它有很大的不同。 – john 2013-04-25 15:40:36
如果使用标准算法,这将会更短,更稳健。 'std :: iota'代替你的第一个内部循环,'std :: random_shuffle'洗牌它们。 'std :: copy'可以输出它们,'std :: vector :: clear'可以重置向量。 – chris 2013-04-25 15:41:46