0

I am receiving the error too many initializers in my deckofcardsclass.cpp class file. I've seen several posts about this, but they don't directly relate and what i'm running into is a bit more complicated since I am populating the array with instances of another class. Is it merely a syntax error? Or is my logic behind the initialization incorrect?

To Be Clear: The error is occurring in the implementation file when initializing the cards_ array

Class Header

#pragma once
#ifndef DECKOFCARDS_H_
#define DECKOFCARDS_H_

#include <array>
#include "Card.h"

class DeckOfCards
{

    public:
        DeckOfCards();
        void printDeck();


    private:
        std::array<Card, 52> cards_;

};


#endif // !1

Class Implementation

#include "stdafx.h"
#include <iostream>
#include "DeckOfCards.h"
#include "Card.h"
#include <array>


DeckOfCards::DeckOfCards()
    :
    cards_
{
    { Card::Diamonds, Card::Two },
    { Card::Diamonds, Card::Three },
    { Card::Diamonds, Card::Four },
    { Card::Diamonds, Card::Five },
    { Card::Diamonds, Card::Six },
    { Card::Diamonds, Card::Seven },
    { Card::Diamonds, Card::Eight },
    { Card::Diamonds, Card::Nine },
    { Card::Diamonds, Card::Ten },
    { Card::Diamonds, Card::Jack },
    { Card::Diamonds, Card::Queen },
    { Card::Diamonds, Card::King },
    { Card::Diamonds, Card::Ace },
    { Card::Hearts, Card::Two },
    { Card::Hearts, Card::Three },
    { Card::Hearts, Card::Four },
    { Card::Hearts, Card::Five },
    { Card::Hearts, Card::Six },
    { Card::Hearts, Card::Seven },
    { Card::Hearts, Card::Eight },
    { Card::Hearts, Card::Nine },
    { Card::Hearts, Card::Ten },
    { Card::Hearts, Card::Jack },
    { Card::Hearts, Card::Queen },
    { Card::Hearts, Card::King },
    { Card::Hearts, Card::Ace },
    { Card::Spades, Card::Two },
    { Card::Spades, Card::Three },
    { Card::Spades, Card::Four },
    { Card::Spades, Card::Five },
    { Card::Spades, Card::Six },
    { Card::Spades, Card::Seven },
    { Card::Spades, Card::Eight },
    { Card::Spades, Card::Nine },
    { Card::Spades, Card::Ten },
    { Card::Spades, Card::Jack },
    { Card::Spades, Card::Queen },
    { Card::Spades, Card::King },
    { Card::Spades, Card::Ace },
    { Card::Clubs, Card::Two },
    { Card::Clubs, Card::Three },
    { Card::Clubs, Card::Four },
    { Card::Clubs, Card::Five },
    { Card::Clubs, Card::Six },
    { Card::Clubs, Card::Seven },
    { Card::Clubs, Card::Eight },
    { Card::Clubs, Card::Nine },
    { Card::Clubs, Card::Ten },
    { Card::Clubs, Card::Jack },
    { Card::Clubs, Card::Queen },
    { Card::Clubs, Card::King },
    { Card::Clubs, Card::Ace } }
{}

void DeckOfCards::printDeck()
{

    bool first = true;

    for (auto card : cards_)
    {
        if (!first)
        {

            std::cout << ", ";

        }
        card.printCard();
        first = false;
    }

}

Card header

#pragma once

#ifndef CARD_H_
#define CARD_H_

struct Card
{

    enum Suit_Type
    {

        Diamonds,
        Hearts,
        Spades,
        Clubs,
    } suit;

    enum Value_Type
    {
        Two = 2,
        Three = 3,
        Four = 4,
        Five = 5,
        Six = 6,
        Seven = 7,
        Eight = 8,
        Nine = 9,
        Ten = 10,
        Jack = 11,
        Queen = 12,
        King = 13,
        Ace = 14
    } value;

    void printCard();

};


#endif // !CARD_H

_

StormsEdge
  • 854
  • 2
  • 10
  • 35
  • And the error you get is? – NathanOliver Jul 15 '16 at 13:12
  • @NathanOliver First line of the paragraph "Too many initializers" – StormsEdge Jul 15 '16 at 13:13
  • That is the extent of the error message? – NathanOliver Jul 15 '16 at 13:13
  • @NathanOliver Yes unfortunately so lol. That's what i'm not understanding. It's giving me lines 13 and 65. Line 13 in the "DeckOfCardsClass.cpp" file is { Card::Diamonds, Card::Three }, and line 65 is the line between the {} and "void DeckOfCards::printDeck() – StormsEdge Jul 15 '16 at 13:17
  • 6
    Add an extra pair of braces: `cards_ {{ { Card::Diamonds, Card::Two }, ... }}`. See also http://stackoverflow.com/questions/27669200/how-should-i-brace-initialize-an-stdarray-of-stdpairs – Igor Tandetnik Jul 15 '16 at 13:19
  • @IgorTandetnik that fixed it, but i'm still not understanding why. Because it operates by rows and columns in an multidimensional array I understand that, but why does adding the two extra braces mean really anything? – StormsEdge Jul 15 '16 at 13:28
  • 3
    `std::array` looks something like this: `template struct array { T arr[N]; };` So it's a struct with a single element that's a plain C array. When you initialize a struct, you generally write `{ initializer_for_element}`. In this case, `initializer_for_element` is itself a braced list (since element is an array) - hence double braces. Often, one pair of braces can be removed thanks to a feature called ["brace elision"](http://en.cppreference.com/w/cpp/language/aggregate_initialization) - but not in this case where the element of the array itself requires brace init list. – Igor Tandetnik Jul 15 '16 at 13:33
  • @Igor Tandetnik You should make that an answer rather than a comment. – Jesper Juhl Jul 15 '16 at 13:58
  • @JesperJuhl I linked to a pre-existing answer in my first comment. – Igor Tandetnik Jul 15 '16 at 14:03

1 Answers1

0

You might find that this stretches you, but where filling an array or vector can be described in algorithmic terms, I'd probably do it that way.

In this case, I have used a constexpr to generate the array, since std::array supports constexpr construction. If you decide to use a vector, a similar approach will work but you'll need to remove the constexpr.

#include <array>
#include <iostream>
#include <utility>
#include <random>
#include <algorithm>

struct Card
{

    enum Suit_Type
    {

        Diamonds,
        Hearts,
        Spades,
        Clubs,
    } suit;
    friend std::ostream& operator<<(std::ostream& os, Suit_Type s) {
        switch (s) {
            case Card::Diamonds: return os << "Diamonds";
            case Card::Hearts: return os << "Hearts";
            case Card::Spades: return os << "Spades";
            case Card::Clubs: return os << "Clubs";
        }
    }

    enum Value_Type
    {
        Two = 2,
        Three = 3,
        Four = 4,
        Five = 5,
        Six = 6,
        Seven = 7,
        Eight = 8,
        Nine = 9,
        Ten = 10,
        Jack = 11,
        Queen = 12,
        King = 13,
        Ace = 14
    } value;

    friend std::ostream& operator<<(std::ostream& os, Value_Type s) {
        switch (s) {
            case Card::Two: return os << "Two";
            case Card::Three: return os << "Three";
            case Card::Four: return os << "Four";
            case Card::Five: return os << "Five";
            case Card::Six: return os << "Six";
            case Card::Seven: return os << "Seven";
            case Card::Eight: return os << "Eight";
            case Card::Nine: return os << "Nine";
            case Card::Ten: return os << "Ten";
            case Card::Jack: return os << "Jack";
            case Card::Queen: return os << "Queen";
            case Card::King: return os << "King";
            case Card::Ace: return os << "Ace";
        }
    }

    void printCard();
};

void Card::printCard() {
    std::cout << value << " of " << suit;
}

constexpr Card card_from_index(int index) {
    return {
        static_cast<Card::Suit_Type>(index / 13),
        static_cast<Card::Value_Type>((index % 13) + 2)
    };
}

class DeckOfCards
{

public:
    DeckOfCards();
    void printDeck();

    template<class Engine>
    void shuffle(Engine&& eng) {
        std::shuffle(std::begin(cards_), std::end(cards_),
                     std::forward<Engine>(eng));
    }

private:
    static constexpr int nof_cards = 52;
    using deck_store = std::array<Card, nof_cards>;

    template<int...Is>
    constexpr static deck_store generate_deck(std::integer_sequence<int, Is...>)
    {
        deck_store result{ card_from_index(Is)... };
        return result;
    }
private:
    deck_store cards_;

};


DeckOfCards::DeckOfCards()
: cards_ (generate_deck(std::make_integer_sequence<int, nof_cards>()))
{}


void DeckOfCards::printDeck()
{

    bool first = true;

    for (auto card : cards_)
    {
        if (!first)
        {

            std::cout << ", ";

        }
        card.printCard();
        first = false;
    }

    std::cout << "\n";

}

int main()
{
    DeckOfCards deck;
    deck.printDeck();

    deck.shuffle(std::default_random_engine { std::random_device {} ()});
    std::cout << "\nafter shuffling:\n\n";
    deck.printDeck();

}
Richard Hodges
  • 68,278
  • 7
  • 90
  • 142