尝试制作一个简单的纸牌游戏程序。我在vector::erase();
类型的向量上使用Card
函数时遇到问题。它似乎无法使用它,因为vector::erase();
中没有处理<Card>
的重载函数。这让我感到困惑,因为矢量是template
d。
#include <iostream>
#include <vector>
#include <algorithm>
enum card_suit {SPADE, CLUB, DIAMOND, HEART};
class Card;
class Player;
class Deck;
class Card
{
unsigned short rank;
card_suit suit;
public:
Card(unsigned short r, card_suit s)
{
rank = r;
suit = s;
}
bool operator == (Card& a)
{
if(this->rank == a.rank && this->suit == a.suit) return true;
else return false;
}
};
class Deck
{
std::vector<Card> cards;
public:
Deck& add_card(Card c)
{
cards.push_back(c);
return *this;
}
Deck& remove_card(Card c)
{
for(std::vector<Card>::iterator i=cards.begin(); i<cards.end(); i++)
{
if(*i==c) cards.erase(cards.begin()-i);
}
return *this;
}
Deck& shuffle()
{
}
};
class Player
{
Deck hand;
unsigned short points;
public:
Player()
{
points=0;
}
};
int main()
{
return 0;
}
知道该怎么做?
答案 0 :(得分:4)
如果您获得正确的基本语法和习语,这通常可以正常工作:
for (std::vector<Card>::iterator it = cards.begin(), end = cards.end(); it != end; ++it)
{
if (c == *it)
{
cards.erase(it);
break;
}
}
请注意,从容器中删除会使迭代器无效,因此我们只能删除一个元素。我们不能在这里使用通常的erase(it++)
,因为擦除后的所有迭代器都会被擦除无效。
为了有效地从向量中删除所有匹配元素,您应该使用remove + erase惯用语:
cards.erase(std::remove(cards.begin(), cards.end(), c), cards.end());
这首先重新排序向量的元素,以便所有匹配c
的元素都在末尾(remove
),然后(有效地)从向量中删除({{1} })。
答案 1 :(得分:1)
如果我不遗漏某些内容,您只需将cards.erase(cards.begin()-i);
替换为cards.erase(i);
即可。真的,我无法理解你的代码是什么意思。
好吧,如果谈论有效性,我猜卡片顺序没有意义,我们可以使用这个功能:
std::vector<Card>::iterator i = std::find( cards.begin(), cards.end(), c );
if ( i != cards.end() ) {
if ( i != (cards.end()-1) )
*i = *(cards.end()-1);
cards.pop_back();
}
*建议的擦除 - 移除组合会产生矢量尾部的副本。
答案 2 :(得分:1)
如果您只想删除一张卡,那么请改为使用
if(*i==c) cards.erase(cards.begin()-i);
这样做:
if(*i==c) cards.erase(i);
答案 3 :(得分:0)
问题是:
cards.begin() - i
// ^^^^
此表达式的结果是ptr_diff 虽然erase()方法采用迭代器。
也许你的意思是:
cards.erase( i );