1

I have a class Player which contains an instance variable: \

vector<Card> userCards;

In order to avoid any compilation errors I forward declared the class Card. However now when I try to Build Solution I get an error saying

Card *: Unknown size.

Basically I am trying to create a Player who contains a non-fixed number of cards, so I tried using a vector and now I cannot get it to work.

Player.h

#include <iostream>
#include <vector>

using std::string;
using std::vector;

#ifndef PLAYER_H_
#define PLAYER_H_

class Card;
class Player {
private:
    vector<Card> userCards;
};
#endif

Card.h

#include <iostream>

using std::string;

#ifndef CARD_H_
#define CARD_H_

class Card {
private:
    string name;
    string type;

public:
    Card(const string& name, const string& type);   
};
#endif

I have a bunch of different functions that are not related, so I did not include them.

LogicStuff
  • 19,397
  • 6
  • 54
  • 74
t3rrh42d2
  • 134
  • 1
  • 2
  • 10
  • Forward declarations can only be used with pointers, not when using the object type itself. – Barmar Oct 21 '15 at 20:40
  • 1
    @Barmar untrue, class declarations can be used for a variety of purposes – M.M Oct 21 '15 at 20:55
  • @M.M According to my knowledge Barmar is correct, you can forward declare the class but when you refer to that class it must be a pointer or reference, not the object by itself: thus 'Card*' works but not 'Card' – CJCombrink Oct 22 '15 at 06:09
  • 1
    @TheBadger [here](http://www.boost.org/doc/libs/1_54_0/doc/html/container.html) are some containers that work with incomplete type (could be used in OP's code instead of `std::vector`) – M.M Oct 22 '15 at 19:32

4 Answers4

5

The type template argument of std::vector cannot be an incomplete type. It has to be defined (complete) before instantiation of std::vector<Card>. To do that, replace your forward declaration class Card; with #include "Card.h" directive.

You can see the further requirements on template arguments here.

LogicStuff
  • 19,397
  • 6
  • 54
  • 74
3

I am assuming you included the Card.h header in the Player.h file using the #include "Card.h" directive

but, if you did not then be informed that std::vector<T> requires its parameter to be a complete type and you cannot pass a forward declared type as its template argument.

Here is a another question/answer that clarifies your problem: When can I use a forward declaration?

Ahmed Akhtar
  • 1,444
  • 1
  • 16
  • 28
2

The vector doesn't have to know how many cards you want to store, but is has to know the size of a Card.

So don't forward declare, but #include the Card.h.

Bo Persson
  • 90,663
  • 31
  • 146
  • 203
2

vector<Card> needs to see a complete declaration of Card. There are some certain functions that are needed for instantiation.

You can do something like a

vector<unique_ptr<Card>> userCards;

though, which behaves as any pointer (reference) declaration, and accepts the forward declaration.

πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190