3

嗨,我在编译一段简单的代码时遇到了麻烦。我正在创建一个实现一副纸牌的类,我想使用 list::short 方法创建一个 shuffle 方法。

相关代码:

甲板.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 */

甲板.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 参考上,我无法在谷歌上找到这个问题的答案。

提前致谢。

4

6 回答 6

10

我能说些什么 :)

首先,不要存储指向 的指针Card,只需将卡片直接存储在容器中即可。如果您出于任何原因坚持存储指向它们的指针,请使用shared_ptr<Card>from 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您的情况存在性能问题,您可以将 typedef 替换为std::deque

typedef std::deque<Card> Deck;
于 2009-09-12T17:20:57.620 回答
7

compareRandom 是一个成员函数,它具有类型bool (Deck::*)(const Card*, const Card*),这意味着您不能将其称为 like f(a,b),这就是 sort 将如何调用它。您可以将 compareRandom 设为静态或独立函数,或使用函子使其适应 Deck 的特定实例。

于 2009-09-12T17:16:31.597 回答
6

顺便说一句 - 你不能使用 sort 来洗牌 :) Sort 对比较函数做了一些假设。

于 2009-09-12T17:22:20.707 回答
3

除了别人说的:你可以使用(我今天学到的东西,万岁!),我可能会补充一点,你不能使用随机函数作为排序标准。std::shuffle std::random_shuffle

sort采用严格的弱排序作为比较器,这意味着如果a < b(或compareRandom(a,b)返回 false,则b < acompareRandom(b,a)返回 true)并且b == a应该返回 false,您永远无法用随机函数保证sort这一点。在这种情况下,行为未定义。我不知道如果它甚至结束...

于 2009-09-12T17:29:03.017 回答
2

Logan Capaldo 回答中的错误原因。现在您可以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() );
}
于 2009-09-12T17:22:08.997 回答
0

我劝你std::random_shuffle改用。它不适用于 alist但它可以用于 a dequeor vector,因此除非您需要列表属性,否则我建议您使用另一个容器。如果您必须使用列表,请尝试以下操作:

void Deck::shuffle()
{
    vector<Card*> temp(cards->begin(), cards->end());
    random_shuffle(temp.begin(), temp.end());
    cards->assign(temp.begin(), temp.end());
}
于 2009-09-12T21:20:35.680 回答