2012-08-14 38 views
0

擦除元件I具有以下矢量存儲類型播放機的元素:使用迭代向量

void game::removePlayer(string name) { 
    vector<player>::iterator begin = players.begin(); 

    // find the player 
    while (begin != players.end()) { 
     if (begin->getName() == name) { 
      break; 
     } 
     ++begin; 
    } 

    if (begin != players.end()) 
     players.erase(begin); 

}

std::vector<player> players; 
在一類稱爲遊戲,其具有以下功能

我收到以下錯誤:

1>------ Build started: Project: texas holdem, Configuration: Debug Win32 ------ 
1> game.cpp 
1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\xutility(2514): error C2582: 'operator =' function is unavailable in 'player' 
1>   c:\program files (x86)\microsoft visual studio 10.0\vc\include\xutility(2535) : see reference to function template instantiation '_OutIt std::_Move<_InIt,_OutIt>(_InIt,_InIt,_OutIt,std::_Nonscalar_ptr_iterator_tag)' being compiled 
1>   with 
1>   [ 
1>    _OutIt=player *, 
1>    _InIt=player * 
1>   ] 
1>   c:\program files (x86)\microsoft visual studio 10.0\vc\include\vector(1170) : see reference to function template instantiation '_OutIt std::_Move<player*,player*>(_InIt,_InIt,_OutIt)' being compiled 
1>   with 
1>   [ 
1>    _OutIt=player *, 
1>    _InIt=player * 
1>   ] 
1>   c:\program files (x86)\microsoft visual studio 10.0\vc\include\vector(1165) : while compiling class template member function 'std::_Vector_iterator<_Myvec> std::vector<_Ty>::erase(std::_Vector_const_iterator<_Myvec>)' 
1>   with 
1>   [ 
1>    _Myvec=std::_Vector_val<player,std::allocator<player>>, 
1>    _Ty=player 
1>   ] 
1>   c:\vcprojects\texas holdem\texas holdem\game.h(29) : see reference to class template instantiation 'std::vector<_Ty>' being compiled 
1>   with 
1>   [ 
1>    _Ty=player 
1>   ] 
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ========== 

去除線

players.erase(begin); 

修正錯誤,爲什麼會發生,雖然,我該如何解決?

+0

作爲樣式說明,我會爲迭代器選擇「begin」以外的名稱,因爲我相信讀者很容易將其與着名的名稱「begin()」混淆。例如,當我看到「players.erase(begin)」這一行時,「我的第一個想法是,」他爲什麼要擦除第一個元素而不是匹配元素?「。 – 2012-08-14 00:59:24

回答

1

您需要爲您的班級播放器重載賦值運算符Player & operator= (const Player & other)。這是因爲erase要求它的參數是可複製的(它需要在移除後重新排列向量的其他元素)。

+2

正確,但要注意「移動」一詞。在C++ 11之前,它很好,但現在它意味着一個類支持移動語義。雖然這對vector :: erase()很有用,但這不是必需的。普通的賦值運算符就足夠了。這些日子的術語是「可複製的」和「可移動的」。 – 2012-08-14 00:44:40

+0

謝謝,很好。編輯。 – cmh 2012-08-14 00:45:58

+0

迂腐的筆記:C++ 03要求與容器一起使用的所有類型都是可複製且可分配的(通常情況下),而不管您可能在容器上執行哪些操作。 C++ 11不太嚴格 - 對包含類型的要求具體取決於您使用容器執行的操作。對於'vector :: erase()',包含的類型必須是'MoveAssignable'。 – 2012-08-14 01:17:17

0

問題是您的Player類不可移動。爲了從矢量的中間移除Player,之後所有的Player必須在矢量中向下移動一個空間。一種解決方案是不使用矢量。另一種是使Player可移動。

1

發生了什麼事是庫代碼通過將該迭代器上方的每個數組元素向下移動一個槽來刪除player對象。爲此,它使用operator =複製每個對象。顯然,player類沒有該運營商。

+0

而且,剛剛指出@cmh在C++ 11中「可移動」是如何改變含義的,我看到我使用了上面的「移動」。嘆。 – 2012-08-14 00:45:38

+0

從好的一面來看,我感覺不那麼糟糕。 – cmh 2012-08-14 00:46:37