在 random_shuffle() 对象向量时出现很多错误?

Posted

技术标签:

【中文标题】在 random_shuffle() 对象向量时出现很多错误?【英文标题】:Getting lots of error while random_shuffle() a vector of objects? 【发布时间】:2019-04-05 05:08:57 【问题描述】:

我正在尝试编写实现 STL 库的德州扑克游戏。目前,我正在创建一个卡片组,它将是对象“卡片”的向量。我坚持使用 random_shuffle() 算法来洗牌。我最终得到了大量的错误。我在安装了 cygwin 的 NetBeans 8.2 上写这个。(我必须) 以下是我得到的错误:

> cd 'C:\Users\vince\Documents\NetBeansProjects\texas_holdem'
> C:\cygwin64\bin\make.exe -f Makefile CONF=Debug "/usr/bin/make" -f
> nbproject/Makefile-Debug.mk QMAKE= SUBPROJECTS= .build-conf make[1]:
> Entering directory
> '/cygdrive/c/Users/vince/Documents/NetBeansProjects/texas_holdem'
> "/usr/bin/make"  -f nbproject/Makefile-Debug.mk
> dist/Debug/Cygwin-Windows/texas_holdem.exe make[2]: Entering directory
> '/cygdrive/c/Users/vince/Documents/NetBeansProjects/texas_holdem'
> mkdir -p build/Debug/Cygwin-Windows rm -f
> "build/Debug/Cygwin-Windows/DeckofCards.o.d" g++    -c -g -s
> -std=c++11 -MMD -MP -MF "build/Debug/Cygwin-Windows/DeckofCards.o.d" -o build/Debug/Cygwin-Windows/DeckofCards.o DeckofCards.cpp DeckofCards.cpp:42:1: error: 'vector' does not name a type; did you
> mean 'perror'?  vector<Cards> DeckofCards::get_Deck() const   ^~~~~~ 
> perror In file included from
> /usr/lib/gcc/x86_64-pc-cygwin/7.4.0/include/c++/bits/char_traits.h:39:0,
>                  from /usr/lib/gcc/x86_64-pc-cygwin/7.4.0/include/c++/string:40,
>                  from /usr/lib/gcc/x86_64-pc-cygwin/7.4.0/include/c++/random:40,
>                  from DeckofCards.cpp:8: /usr/lib/gcc/x86_64-pc-cygwin/7.4.0/include/c++/bits/stl_algobase.h:
> In instantiation of 'void std::iter_swap(_ForwardIterator1,
> _ForwardIterator2) [with _ForwardIterator1 = __gnu_cxx::__normal_iterator<Cards*, std::vector<Cards> >; _ForwardIterator2 = __gnu_cxx::__normal_iterator<Cards*, std::vector<Cards> >]':
> /usr/lib/gcc/x86_64-pc-cygwin/7.4.0/include/c++/bits/stl_algo.h:4582:22:
> required from 'void std::random_shuffle(_RAIter, _RAIter) [with
> _RAIter = __gnu_cxx::__normal_iterator<Cards*, std::vector<Cards> >]' DeckofCards.cpp:46:61:   required from here
> /usr/lib/gcc/x86_64-pc-cygwin/7.4.0/include/c++/bits/stl_algobase.h:148:11:
> error: no matching function for call to 'swap(Cards&, Cards&)'
>        swap(*__a, *__b);
>        ~~~~^~~~~~~~~~~~ In file included from /usr/lib/gcc/x86_64-pc-cygwin/7.4.0/include/c++/bits/stl_pair.h:59:0,
>                  from /usr/lib/gcc/x86_64-pc-cygwin/7.4.0/include/c++/bits/stl_algobase.h:64,
>                  from /usr/lib/gcc/x86_64-pc-cygwin/7.4.0/include/c++/bits/char_traits.h:39,
>                  from /usr/lib/gcc/x86_64-pc-cygwin/7.4.0/include/c++/string:40,
>                  from /usr/lib/gcc/x86_64-pc-cygwin/7.4.0/include/c++/random:40,
>                  from DeckofCards.cpp:8: /usr/lib/gcc/x86_64-pc-cygwin/7.4.0/include/c++/bits/move.h:187:5:
> note: candidate: template<class _Tp> typename
> std::enable_if<std::__and_<std::__not_<std::__is_tuple_like<_Tp> >,
> std::is_move_constructible<_Tp>, std::is_move_assignable<_Tp>
> >::value>::type std::swap(_Tp&, _Tp&)
>      swap(_Tp& __a, _Tp& __b)
>      ^~~~ /usr/lib/gcc/x86_64-pc-cygwin/7.4.0/include/c++/bits/move.h:187:5:
> note:   template argument deduction/substitution failed:
> /usr/lib/gcc/x86_64-pc-cygwin/7.4.0/include/c++/bits/move.h: In
> substitution of 'template<class _Tp> typename
> std::enable_if<std::__and_<std::__not_<std::__is_tuple_like<_Tp> >,
> std::is_move_constructible<_Tp>, std::is_move_assignable<_Tp>
> >::value>::type std::swap(_Tp&, _Tp&) [with _Tp = Cards]': /usr/lib/gcc/x86_64-pc-cygwin/7.4.0/include/c++/bits/stl_algobase.h:148:11:
> required from 'void std::iter_swap(_ForwardIterator1,
> _ForwardIterator2) [with _ForwardIterator1 = __gnu_cxx::__normal_iterator<Cards*, std::vector<Cards> >; _ForwardIterator2 = __gnu_cxx::__normal_iterator<Cards*, std::vector<Cards> >]'
> /usr/lib/gcc/x86_64-pc-cygwin/7.4.0/include/c++/bits/stl_algo.h:4582:22:
> required from 'void std::random_shuffle(_RAIter, _RAIter) [with
> _RAIter = __gnu_cxx::__normal_iterator<Cards*, std::vector<Cards> >]' DeckofCards.cpp:46:61:   required from here
> /usr/lib/gcc/x86_64-pc-cygwin/7.4.0/include/c++/bits/move.h:187:5:
> error: no type named 'type' in 'struct std::enable_if<false, void>'
> /usr/lib/gcc/x86_64-pc-cygwin/7.4.0/include/c++/bits/stl_algobase.h:
> In instantiation of 'void std::iter_swap(_ForwardIterator1,
> _ForwardIterator2) [with _ForwardIterator1 = __gnu_cxx::__normal_iterator<Cards*, std::vector<Cards> >; _ForwardIterator2 = __gnu_cxx::__normal_iterator<Cards*, std::vector<Cards> >]':
> /usr/lib/gcc/x86_64-pc-cygwin/7.4.0/include/c++/bits/stl_algo.h:4582:22:
> required from 'void std::random_shuffle(_RAIter, _RAIter) [with
> _RAIter = __gnu_cxx::__normal_iterator<Cards*, std::vector<Cards> >]' DeckofCards.cpp:46:61:   required from here
> /usr/lib/gcc/x86_64-pc-cygwin/7.4.0/include/c++/bits/move.h:210:5:
> note: candidate: template<class _Tp, long unsigned int _Nm> typename
> std::enable_if<std::__is_swappable<_Tp>::value>::type std::swap(_Tp
> (&)[_Nm], _Tp (&)[_Nm])
>      swap(_Tp (&__a)[_Nm], _Tp (&__b)[_Nm])
>      ^~~~ /usr/lib/gcc/x86_64-pc-cygwin/7.4.0/include/c++/bits/move.h:210:5:
> note:   template argument deduction/substitution failed: In file
> included from
> /usr/lib/gcc/x86_64-pc-cygwin/7.4.0/include/c++/bits/char_traits.h:39:0,
>                  from /usr/lib/gcc/x86_64-pc-cygwin/7.4.0/include/c++/string:40,
>                  from /usr/lib/gcc/x86_64-pc-cygwin/7.4.0/include/c++/random:40,
>                  from DeckofCards.cpp:8: /usr/lib/gcc/x86_64-pc-cygwin/7.4.0/include/c++/bits/stl_algobase.h:148:11:
> note:   mismatched types '_Tp [_Nm]' and 'Cards'
>        swap(*__a, *__b);
>        ~~~~^~~~~~~~~~~~ In file included from /usr/lib/gcc/x86_64-pc-cygwin/7.4.0/include/c++/bits/stl_algobase.h:64:0,
>                  from /usr/lib/gcc/x86_64-pc-cygwin/7.4.0/include/c++/bits/char_traits.h:39,
>                  from /usr/lib/gcc/x86_64-pc-cygwin/7.4.0/include/c++/string:40,
>                  from /usr/lib/gcc/x86_64-pc-cygwin/7.4.0/include/c++/random:40,
>                  from DeckofCards.cpp:8: /usr/lib/gcc/x86_64-pc-cygwin/7.4.0/include/c++/bits/stl_pair.h:495:5:
> note: candidate: template<class _T1, class _T2> void
> std::swap(std::pair<_T1, _T2>&, std::pair<_T1, _T2>&)
>      swap(pair<_T1, _T2>& __x, pair<_T1, _T2>& __y)
>      ^~~~ /usr/lib/gcc/x86_64-pc-cygwin/7.4.0/include/c++/bits/stl_pair.h:495:5:
> note:   template argument deduction/substitution failed: In file
> included from
> /usr/lib/gcc/x86_64-pc-cygwin/7.4.0/include/c++/bits/char_traits.h:39:0,
>                  from /usr/lib/gcc/x86_64-pc-cygwin/7.4.0/include/c++/string:40,
>                  from /usr/lib/gcc/x86_64-pc-cygwin/7.4.0/include/c++/random:40,
>                  from DeckofCards.cpp:8: /usr/lib/gcc/x86_64-pc-cygwin/7.4.0/include/c++/bits/stl_algobase.h:148:11:
> note:   'Cards' is not derived from 'std::pair<_T1, _T2>'
>        swap(*__a, *__b);
>        ~~~~^~~~~~~~~~~~ make[2]: *** [nbproject/Makefile-Debug.mk:75: build/Debug/Cygwin-Windows/DeckofCards.o] Error 1 make[2]: Leaving
> directory
> '/cygdrive/c/Users/vince/Documents/NetBeansProjects/texas_holdem'
> make[1]: *** [nbproject/Makefile-Debug.mk:61: .build-conf] Error 2
> make[1]: Leaving directory
> '/cygdrive/c/Users/vince/Documents/NetBeansProjects/texas_holdem'
> make: *** [nbproject/Makefile-impl.mk:40: .build-impl] Error 2

我对编码还很陌生。谁能告诉我我在这里做错了什么?任何帮助将不胜感激:)

卡片.h:

#ifndef CARDS_H
#define CARDS_H
#include <string>

class Cards 
    private:
        int rank;
        int suit;
        const int LOWEST_RANK = 0;
        const int HIGHEST_RANK = ACE;

    public:
        //In Texas hold'em, clubs is the lowest rank, and spades is the highest rank, hence clubs = 0 and spades = 3. 
        enum SUIT
            CLUBS, DIAMONDS, HEARTS, SPADES
        ;
        enum FACE 
            JACK = 11, QUEEN = 12, KING = 13, ACE = 14
        ;
        Cards(int rank, int suit);
        int getRank() const;
        int getSuit() const;
        std::string toString() const;
        std::string rankToString(int rank) const;
        std::string suitToString(int suit) const;
;

std::ostream& operator<<(std::ostream& os, const Cards& c);

#endif /* CARDS_H */

卡片.cpp:

#include "Cards.h"
#include <assert.h>

Cards::Cards(int rank, int suit) 
    this->rank = rank;
    this->suit = suit;
    assert(suit == CLUBS || suit == DIAMONDS || suit == HEARTS || suit == SPADES);
    assert(rank >= LOWEST_RANK && rank <= ACE);


int Cards::getRank() const
    return rank;


int Cards::getSuit() const
    return suit;


std::string Cards::rankToString(int rank) const
    switch (rank)
        case (JACK):
            return "Jack";
            break;
        case (QUEEN):
            return "Queen";
            break;
        case (KING):
            return "King";
            break;
        case (ACE):
            return "Ace";
            break;
        default:
            return std::to_string(rank);
    


std::string Cards::suitToString(int suit) const
    switch (suit) 
        case (CLUBS):
            return "Clubs";
            break;
        case (SPADES):
            return "Spades";
            break;
        case (DIAMONDS):
            return "Diamonds";
            break;
        case (HEARTS):
            return "Hearts";
    


std::string Cards::toString() const
    std::string retval;

    if (rank < 11)
        retval = rankToString(rank);
    else if (rank == JACK)
        retval = "J";
    else if (rank == QUEEN)
        retval = "Q";
    else if (rank == KING)
        retval = "K";
    else if (rank == ACE)
        retval = "A";

    switch (suit) 
        case (HEARTS):
            retval += "H";
            break;
        case (CLUBS):
            retval += "C";
            break;
        case (DIAMONDS):
            retval += "D";
            break;
        case (SPADES):
            retval += "S";
            break;
    

    return retval;




std::ostream& operator<< (std::ostream& os, const Cards& c) 
    os << c.toString();

    return os;

DeckofCards.h:

#ifndef DECKOFCARDS_H
#define DECKOFCARDS_H
#include "Cards.h"
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>

class DeckofCards 
    private:
        std::vector<Cards> deck;
        const int CAPACITY = 52;
        int cards_left;
        std::vector<Cards>& get_Deck() const;

    public:
        DeckofCards();  
        ~DeckofCards();
        void shuffleDeck();
        Cards draw();
        int getCardsLeft();
        void burn_a_Card();

;


#endif /* DECKOFCARDS_H */

DeckofCards.cpp:

#include <random>

#include "DeckofCards.h"

DeckofCards::DeckofCards() 
    cards_left = CAPACITY;

    for (int i = 0; i <= 13; i++) 
        deck.push_back(Cards(i, Cards::CLUBS));
        deck.push_back(Cards(i, Cards::DIAMONDS));
        deck.push_back(Cards(i, Cards::HEARTS));
        deck.push_back(Cards(i, Cards::SPADES));
    

    shuffleDeck();


DeckofCards::~DeckofCards() 
    while (!deck.empty())
        deck.pop_back();
    

    cards_left = 0;


void DeckofCards::burn_a_Card() 
    if (getCardsLeft() > 0) 
        deck.pop_back();
        cards_left--;
    
    else 
        std::cout << "Burn failed. There is no card left in the deck!" << std::endl;
    

vector<Cards> DeckofCards::get_Deck() const 
    return deck;

void DeckofCards::shuffleDeck()
    std::random_shuffle(get_Deck().begin(), get_Deck().end());



Cards DeckofCards::draw()
    //shuffleDeck();

    if (getCardsLeft() > 0) 
        return deck.back();
        cards_left--;
    
    else 
        std::cout << "Draw failed. There is no card left in the deck!" << std::endl;
    


int DeckofCards::getCardsLeft()
    return cards_left;

这个程序还不完整,但是当我测试它时,我很确定shuffle算法有问题,因为如果我不做shuffle,它会成功运行。关于我拥有的数组,使用 shuffle 或 random_shuffle 算法的正确方法是什么?我对编码相当陌生。任何帮助将不胜感激:)

【问题讨论】:

不要使用std::random_shuffle。它已在 C++17 中删除。使用std::shuffle。 发布时的一些建议——如果问题在于调用random_shuffle,为什么不简单地编写一个尝试使用您创建的向量调用random_shuffle 的3 行程序?为什么我们需要查看您的整个Card 逻辑?这就是minimal reproducible example 的含义。 Here is an example。程序员熟悉他们没有使用过的概念的方式是程序员应该编写小的测试程序和/或函数来习惯这个概念。一旦他们熟悉了,新概念就会被引入到更大的项目中。 【参考方案1】:

这个:

vector<Cards> DeckofCards::get_Deck() const

应该是:

std::vector<Cards> DeckofCards::get_Deck() const

【讨论】:

以上是关于在 random_shuffle() 对象向量时出现很多错误?的主要内容,如果未能解决你的问题,请参考以下文章

C++常用算法random_shuffle

调用将对象向量作为参数的函数时出现链接错误

使用管理器和向量时出现内存错误

在 C++ 中将类实例添加到对象层次结构时出现问题

创建函数变体向量时出现“调用没有匹配函数”错误

关于random_shuffle的一个疑问