2013-04-25 99 views
0

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

回答

8

您無法直接從向量中刪除(向量是序列容器,而不是關聯容器):您需要爲要刪除的元素提供迭代器。

爲了得到一個迭代,則可以:

  • 發現根據其值的元件(通過使用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 << * it; POSS。擦除(it);' – Chowlett 2013-04-25 15:42:15

+0

@Chowlett:重新閱讀這個問題,看起來你是對的。起初,我認爲「隨機」是OP想要擦除的*值*,而不是它的位置。但事實可能並非如此,所以我更新了我的答案以涵蓋兩種情況。謝謝 – 2013-04-25 15:50:11

3

你必須通過一個迭代器來擦除。所以試試

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

0

向量擦除函數採用迭代器不值。 而且您還需要檢查邊界條件,以查看您正在擦除的索引是否不受限制。

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