0

I'm trying to push_back multiple items to a vector. But it's not letting me and it gives me an error.

I've checked online and saw that people have used the push_back function like me and had it work. I assumed it would be the fact that I just can't push_back multiple items, so I removed the extra passing value and I still got the same error.

Function that is getting the error (the red line is under the dot before the push_back function):

originalCardDeck.push_back(card::suitType::CLUBS, card::rankType::TWO);

The class containing the vectors.

class deck
{
public:
    deck()
    {
        originalCardDeck.push_back(card::suitType::CLUBS, card::rankType::TWO);
    }

    ~deck();

    void printDeck(int deck[]);

private:

    vector<card>originalCardDeck;
    vector<card>shuffledCardDeck;
};

The card class containing the enumerated types.

class card
{
public:

    card();

    ~card();

    enum class rankType
    {
        TWO = 2,
        THREE,
        FOUR,
        FIVE,
        SIX,
        SEVEN,
        EIGHT,
        NINE,
        TEN,
        JACK,
        QUEEN,
        KING,
        ACE
    };

    enum class suitType
    {
        CLUBS,
        DIAMONDS,
        HEARTS,
        SPADES

private:
        rankType rank;
        suitType suit;
    };

I'm getting an error saying:

C++ no instance of overloaded function matches the argument list
argument types are: (card::suitType, card::rankType)            
object type is: std::vector<card, std::allocator<card>>

My intention for this line is to have the ability to push_back an element containing multiple data types into a vector, so I can reference it as one later. I would have put it in a for loop if there was no error message.

oss
  • 115
  • 8
  • 2
    If you really "checked online", can you cite some references that claim that `push_back()` takes two or more parameters, which is what you're doing? Perhaps instead of checking online, you will find some higher quality information and more informative and useful C++ learning material in [in a good C++ book](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list)? – Sam Varshavchik Sep 03 '19 at 00:24
  • @SamVarshavchik https://stackoverflow.com/questions/18104928/how-to-push-back-multiple-values-into-a-vector https://stackoverflow.com/questions/45080937/push-back-multiple-types-of-data-in-a-vector-in-c/45080981#45080981https://stackoverflow.com/questions/45080937/push-back-multiple-types-of-data-in-a-vector-in-c/45080981#45080981. This may look irrelevant, but it looked like what I'm trying to do. – oss Sep 03 '19 at 00:26
  • BTW, neither of `card::suitType::CLUBS` or `card::rankType::TWO` is a card. – Jarod42 Sep 03 '19 at 00:29
  • 1
    The cited question does not pass two values to `push_back()`. Did you happen to notice the `{` and `}` symbols in there. These kinds of things really mean things, in C++. They're not just some decoration, of some sort, that the compiler ignores. This is an example of using modern C++'s uniform initialization syntax to pass a *single* object to `push_back()` that's constructed by passing `x` and `y` to the object's ***constructor***, and has nothing to do with `push_back()` itself. – Sam Varshavchik Sep 03 '19 at 00:34
  • @SamVarshavchik That makes a lot of sense. It's a lot similar to what Fareeish suggested. I'm going to review his answer and try to compare it to what I have. – oss Sep 03 '19 at 00:44

2 Answers2

0

You have several issues:

  • You can push_back only one item at a time.

  • Card doesn't have constructor with 2 parameters:

You can do:

card(suitType, rankType) {/*..*/}

and

deck()
{
    originalCardDeck.push_back({card::suitType::CLUBS, card::rankType::TWO})
}

For deck, you can directly initialize vector without push_back:

deck() : originalCardDeck{{card::suitType::CLUBS, card::rankType::TWO}}
{
}
Jarod42
  • 203,559
  • 14
  • 181
  • 302
  • `originalCardDeck` holds `card`s. Neither `card::suitType::CLUBS` nor `card::rankType::TWO` is a `card`. How is that supposed to work? – Fureeish Sep 03 '19 at 00:22
  • @Fureeish: Answering the first issue found, without notifying the second one immediately. Both errors should be fixed now. – Jarod42 Sep 03 '19 at 00:27
  • @Fureeish I assumed it would work since CLUBS and TWO are under different enums but in the same class. – oss Sep 03 '19 at 00:30
  • @AngoMango please refer to my answer. You only defined enums inside your class. You did not specify that a `card` holds a *rank* and a *suite*. I would generally advise **not** to assume things regarding C++, especially when starting to learn it. – Fureeish Sep 03 '19 at 00:33
  • @Fureeish Sorry, I honestly forgot to include my private group of members. It does include a rank and suit. – oss Sep 03 '19 at 00:42
  • Can you explain to me what it means to enclose the push_back parameter list with {...}? According to another user, it's referencing a constructor of the card class, but how would it know that it's supposed to do that with the code you have? Fareeish had the same thing but had the word "card" before the curly braces, which is clear to me that it's calling the constructor. – oss Sep 03 '19 at 00:47
  • `card{card::suitType::CLUBS, card::rankType::TWO}` use explicit `card` whereas `{card::suitType::CLUBS, card::rankType::TWO}` uses same constructor but used "expected" type. `std::vector::push_back` expects a `T`, so in your case `card`. – Jarod42 Sep 03 '19 at 00:52
  • @Jarod42 Ah, so the only difference is that your code is compatible with multiple class objects. – oss Sep 03 '19 at 00:55
0

First of all, in your card class, you defined two enum class types but you did not specify that a card consists of a rankType and a suitType. I suggest adding the fields:

rankType rank;
suitType suit;

to your card class.

Then, the second problem lies in the fact that you are trying to push_back a card with just specifying the rankType and suitType. You either first need to construct a card and then push_back it into the vector, or use emplace_back to create a card inside the vector using arguments used to construct a card. To use the push_back approach, you may replace:

originalCardDeck.push_back(card::suitType::CLUBS, card::rankType::TWO);

with:

originalCardDeck.push_back(card{card::suitType::CLUBS, card::rankType::TWO});

but you would need a constructor that initialises the suit and rank, like this one:

card(suitType suit, rankType rank) : suit(suit), rank(rank) { }

Having that constructor, it'd be better to actually use emplace_back here:

originalCardDeck.emplace_back(card::suitType::CLUBS, card::rankType::TWO);

which constructs a card inside the vector instead of creating a temporary and then copying it (move due to rvalue reference here does a simple copy) to said vector.

Fureeish
  • 12,533
  • 4
  • 32
  • 62
  • We haven't learned about emplace_back, so I would want to stick with the material that we have gone over so far. So with the push_back line you're suggesting, it's pushing a card object into the vector containing a value from the two enumerated types. If I put this in a for loop, will that mean my vector will contain multiple card objects that hold two enumerated types of my choosing? Like a dynamic array of objects? – oss Sep 03 '19 at 00:54
  • 1
    @AngoMango yes, exactly. – Fureeish Sep 03 '19 at 00:59