嗨,我在编写一段简单的代码时遇到了麻烦。我正在创建一个实现卡片组的类,我想使用list :: short方法创建一个shuffle方法。
相关代码:
加入deck.h
#ifndef _DECK_H
#define _DECK_H
#include <list>
#include <ostream>
#include "Card.h"
#include "RandomGenerator.h"
using namespace std;
class Deck {
private:
static const int CARD_NUMBER = Card::CARDS_PER_SUIT*Card::SUIT_NUMBER;
list<Card *> *cards;
RandomGenerator rg;
public:
Deck();
~Deck();
void shuffle();
private:
bool const compareRandom(const Card *a, const Card *b);
};
#endif /* _DECK_H */
deck.cc:
#include "Deck.h"
/**
* Fills the deck with a set of 52 cards
*/
Deck::Deck() {
cards = new list<Card *>();
for(int i = 0; i < CARD_NUMBER; i++)
cards->push_back(
new Card(
Card::Suit(int(i/Card::CARDS_PER_SUIT)),
i%Card::CARDS_PER_SUIT)
);
}
Deck::~Deck() {
gather();
for(list<Card *>::iterator c = cards->begin(); c != cards->end(); c++)
delete *c;
delete cards;
}
bool const Deck::compareRandom(const Card *a, const Card *b) {
return rg.randomBool();
}
void Deck::shuffle() {
cards->sort(compareRandom);
}
编译器显示下一条消息(忽略行号):
Deck.cc: In member function ‘void Deck::shuffle()’:
Deck.cc:66: error: no matching function for call to ‘std::list<Card*, std::allocator<Card*> >::sort(<unresolved overloaded function type>)’
/usr/include/c++/4.3/bits/list.tcc:303: note: candidates are: void std::list<_Tp, _Alloc>::sort() [with _Tp = Card*, _Alloc = std::allocator<Card*>]
/usr/include/c++/4.3/bits/list.tcc:380: note: void std::list<_Tp, _Alloc>::sort(_StrictWeakOrdering) [with _StrictWeakOrdering = const bool (Deck::*)(const Card*, const Card*), _Tp = Card*, _Alloc = std::allocator<Card*>]
问题必须在compareRandom引用上,我没有正确使用,我找不到谷歌搜索这个问题的答案。
提前致谢。
答案 0 :(得分:10)
我可以说些什么:)
首先,不要存储指向Card
的指针,只需将卡片直接存放在容器中即可。如果您因任何原因坚持要存储指针,请使用shared_ptr<Card>
中的Boost
。其次,您可以使用std::random_shuffle
并将random-number-generator
传递给它,而不是实现您的随机播放功能。
我可以再说一遍:)
这是我的想法,除非你出于某种原因必须使用list
,尽管我没有see
这个理由。
#include <iostream>
#include <vector>
#include <deque>
#include <algorithm>
class Card
{
// ...
};
int main()
{
typedef std::vector<Card> Deck;
Deck deck;
// ... fill deck with cards.
// There is an optional third parameter,
// if you need to pass YOUR random-number-generator!
// If you do, I recommend Boost implementation.
std::random_shuffle(deck.begin(), deck.end());
}
我喜欢直接在C++
处理容器,尽管你可能不喜欢它。另外,如果您发现std::vector
在您的案例中存在性能问题,则可以使用std::deque
替换typedef:
typedef std::deque<Card> Deck;
答案 1 :(得分:7)
compareRandom是一个成员函数,它有bool (Deck::*)(const Card*, const Card*)
类型,这意味着你不能像f(a,b)
那样调用它,这就是排序调用它的方式。您可以将compareRandom设置为静态或独立功能,或使用仿函数使其适应特定的Deck实例。
答案 2 :(得分:6)
顺便说一句 - 你不能使用sort来改组:) Sort对比较函数做了一些假设。
答案 3 :(得分:3)
除了别人说的话:你可以使用 std::shuffle
std::random_shuffle
(我今天学到的东西,欢呼!),我可能会加你不能使用随机函数作为排序标准。
sort
采用严格的弱排序作为比较器,这意味着如果a < b
(或compareRandom(a,b)
返回false,则b < a
(compareRandom(b,a)
返回true)并且b == a
应该返回false,这是一个随机函数无法保证的。sort
的行为在这种情况下是未定义的。我不知道它是否会结束......
答案 4 :(得分:2)
Logan Capaldo's answer中出错的原因。现在,您可以通过以下方式将compareRandom
替换为仿函数:
...
private:
struct compareRandom {
// it shouldn't give a random compare result.
// sort will not work (in Visual C++ 2008 it gives runtime assert)
bool operator()(const Card *a, const Card *b) { return rg.randomBool(); }
};
...
然后使用它
void Deck::shuffle() {
cards->sort( compareRandom() );
}
答案 5 :(得分:0)
我建议你改用std::random_shuffle
。它不适用于list
,但它适用于deque
或vector
,因此除非您需要列表属性,否则我建议您使用其他容器。如果您必须使用列表,请尝试以下:
void Deck::shuffle()
{
vector<Card*> temp(cards->begin(), cards->end());
random_shuffle(temp.begin(), temp.end());
cards->assign(temp.begin(), temp.end());
}