代码之家  ›  专栏  ›  技术社区  ›  eliocs

C++自定义比较函数列表::排序

  •  3
  • eliocs  · 技术社区  · 15 年前

    嗨,我在编译一段简单的代码时遇到问题。我正在创建一个实现卡片组的类,我想使用list::short方法创建一个shuffle方法。

    相关代码:

    甲板上

    #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*>]
    

    这个问题必须在我没有正确使用的比较引用上,我找不到谷歌搜索这个问题的答案。

    事先谢谢。

    6 回复  |  直到 15 年前
        1
  •  10
  •   Khaled Alshaya    15 年前

    我能说点什么吗?)

    首先,不要存储指向 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 在您的案例中有性能问题,您可以将typedef替换为 std::deque :

    typedef std::deque<Card> Deck;
    
        2
  •  7
  •   Logan Capaldo    15 年前

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

        3
  •  6
  •   agsamek    15 年前

    顺便说一句,您不能使用sort:)来无序排列。sort对compare函数做了一些假设。

        4
  •  3
  •   xtofl Adam Rosenfield    15 年前

    除了别人说的:你可以用 std::shuffle std::random_shuffle (我今天学到的东西,休瑞!),我可以加上你 不能 使用随机函数作为排序标准。

    sort 采用严格的弱序作为比较器,这意味着如果 a < b (或) compareRandom(a,b) 返回false,然后 b < a ( compareRandom(b,a) 返回true)和 b == a 应该返回false,这是用随机函数无法保证的。行为 分类 在这种情况下是未定义的。我不知道它是否会结束…

        5
  •  2
  •   Community CDub    8 年前

    错误的原因 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() );
    }
    
        6
  •  0
  •   rlbond    15 年前

    我劝你用 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());
    }