使用迭代向量

问题描述:

擦除元件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

您需要为您的班级播放器重载赋值运算符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

问题是您的Player类不可移动。为了从矢量的中间移除Player,之后所有的Player必须在矢量中向下移动一个空间。一种解决方案是不使用矢量。另一种是使Player可移动。

发生了什么事是库代码通过将该迭代器上方的每个数组元素向下移动一个槽来删除player对象。为此,它使用operator =复制每个对象。显然,player类没有该运营商。

+0

而且,刚刚指出@cmh在C++ 11中“可移动”是如何改变含义的,我看到我使用了上面的“移动”。叹。 – 2012-08-14 00:45:38

+0

从好的一面来看,我感觉不那么糟糕。 – cmh 2012-08-14 00:46:37