mercredi 27 novembre 2019

template argument was not declared in this scope

Why am I having issues compiling this in g++ 4.8.5, -std=c++11 -O2 -lm?

#include <algorithm>
#include <array>
#include <iostream>
#include <iterator>
#include <numeric>
#include <sstream>
#include <utility>

template<uint_fast32_t N>
class Jollo
{
private:
    template<uint_fast32_t c>
    struct Player
    {
        int_fast32_t cards[c]; // This line is OK!
        uint_fast32_t nsize = c; // error 'c' was not declared in this scope
        friend std::istream& operator>>(std::istream& is, Player& p)
        {
            for(auto& i : p.cards){
                is >> i;
            }
            return is;
        }

    };
private:
    enum JP_ID{ JPID_PRINCE = N+1, JPID_PRINCESS, JPID_NONE };
    Player<2> m_Prince;
    Player<3> m_Princess;
    int_fast32_t deck[N];
    constexpr static int_fast32_t RoundsToWin {2};
    int_fast32_t NextAvailableCard(const JP_ID& idPlayer, int_fast32_t lastPlayedCard = 0);
public:
    Jollo<N>(){
        static_assert( N>4, "Invalid deck size - JolloManager");
    }

    bool Read();
    int_fast32_t GetWinningCard();
};

template<uint_fast32_t N>
bool Jollo<N>::Read()
{
    static std::string line;
    std::getline(std::cin, line);
    std::istringstream issline(line);
    issline >> m_Princess;
    issline >> m_Prince;
    return (m_Princess.cards[0] != 0);
}

template<uint_fast32_t N>
int_fast32_t Jollo<N>::NextAvailableCard(const JP_ID& idPlayer, int_fast32_t lastPlayedCard)
{
    if(idPlayer == JPID_PRINCE)
    {
        for(int_fast32_t i{0}; i<m_Prince.nsize; ++i) {

            if(deck[m_Prince.cards[i] - 1] != JPID_PRINCE){
               deck[m_Prince.cards[i] - 1] =  JPID_PRINCE;
               return m_Prince.cards[i];
            }
        }
    } else
    if(idPlayer == JPID_PRINCESS)
    {
        for(int_fast32_t i{0}; i<m_Princess.nsize; ++i) {
            if(deck[m_Princess.cards[i] - 1] != JPID_PRINCESS && deck[m_Princess.cards[i] - 1] > lastPlayedCard) {
               deck[m_Princess.cards[i] - 1] =  JPID_PRINCESS;
               return m_Princess.cards[i];
            }
        }
        //no card was higher, return lowest available card
        for(int_fast32_t i{0}; i<m_Princess.nsize; ++i) {
            if(deck[m_Princess.cards[i] - 1] != JPID_PRINCESS) {
               deck[m_Princess.cards[i] - 1] =  JPID_PRINCESS;
               return m_Princess.cards[i];
            }
        }
    }

    for(uint_fast32_t i{0}; i<N; i++)
    {
        if(deck[i] != JPID_PRINCE && deck[i] != JPID_PRINCESS && deck[i] > lastPlayedCard ) {
            return deck[i];
        }
    }
    return -1;
}

template<uint_fast32_t N>
int_fast32_t Jollo<N>::GetWinningCard()
{
    std::iota(deck, deck + N, 1);
    std::sort(m_Prince.cards, m_Prince.cards + m_Prince.nsize, std::greater<int_fast32_t>());
    std::sort(m_Princess.cards, m_Princess.cards + m_Princess.nsize);

    int_fast32_t princeWins {0};
    int_fast32_t princessWins {0};

    for(int_fast32_t round {0}; round < RoundsToWin; ++round) //play two first rounds
    {
        int_fast32_t princeCard = NextAvailableCard(JPID_PRINCE);
        int_fast32_t princessCard = NextAvailableCard(JPID_PRINCESS, princeCard);

        if(princessCard > princeCard){
            ++princessWins;
        } else {
            ++princeWins;
        }
    }
    int_fast32_t lastPrincessCard = NextAvailableCard(JPID_PRINCESS); //important to flip the last card on the deck before continuing
    if(princessWins == RoundsToWin){
        return -1;
    }
    if(princeWins == RoundsToWin){
        return NextAvailableCard(JPID_NONE);
    }
    return NextAvailableCard(JPID_NONE, lastPrincessCard);
}

int main()
{
    Jollo<52u> jollo;
    while(true)
    {
        if(!jollo.Read()) {
            break;
        }
        std::cout << jollo.GetWinningCard() << '\n';
    }
    return 0;
}

I can compile it on almost any other g++ version with c++11 flags.

Aucun commentaire:

Enregistrer un commentaire