矢量擦除错误

问题描述:

我在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

这是为什么和我该如何纠正它?

+1

http://en.cppreference.com/w/cpp/container/vector/erase – hmjd 2013-04-25 15:39:34

+0

你试图抹掉随机位置,或者随机值?它有很大的不同。 – john 2013-04-25 15:40:36

+0

如果使用标准算法,这将会更短,更稳健。 'std :: iota'代替你的第一个内部循环,'std :: random_shuffle'洗牌它们。 'std :: copy'可以输出它们,'std :: vector :: clear'可以重置向量。 – chris 2013-04-25 15:41:46

您无法直接从向量中删除(向量是序列容器,而不是关联容器):您需要为要删除的元素提供迭代器。

为了得到一个迭代,则可以:

  • 发现根据其值的元件(通过使用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); 
+0

在这种情况下,我认为他很可能想要'std :: vector :: iterator it = poss.begin()+ random; std :: cout Chowlett 2013-04-25 15:42:15

+0

@Chowlett:重新阅读这个问题,看起来你是对的。起初,我认为“随机”是OP想要擦除的*值*,而不是它的位置。但事实可能并非如此,所以我更新了我的答案以涵盖两种情况。谢谢 – 2013-04-25 15:50:11

你必须通过一个迭代器来擦除。所以试试

poss.erase(poss.begin() + random); 
+0

我认为这是一个正确的答案,但Andy Prowl可能是对的。 – john 2013-04-25 15:41:26

+0

@john是的,我同意,我将编辑我的帖子,说我不确定OP的意图是什么。我还担心OP的循环会越过数组的终点 - 我想更多地分析逻辑以说服自己没关系(或者可能只是添加一些内容来检查,例如在[assert(random) TooTone 2013-04-25 15:44:00

向量擦除函数采用迭代器不值。 而且您还需要检查边界条件,以查看您正在擦除的索引是否不受限制。

std::vector<int>::iterator itr = poss.begin() + random; 
if(itr != poss.end()) 
{ 
    poss.erase(itr); 
} 
+0

你所做的边界检查是非常不够的,它会检查迭代器对一个可能的无效值,当然,形成任何迭代器都是未定义的行为因此,如果你真的想做一个边界检查,你应该在整数上完成它,然后将它添加到'poss.begin()'中。当然,如果你完全控制了生成整数,就像这里的情况一样,这就是整数的值应该被绑定的地方:'int random = rand()%poss.size();'。任何额外的检查都是多余的。 – 2013-04-25 16:37:31