0

My question is simple: Can you have something like this:

class A {
    B<A> member;
}

Here is a very simplified version of my program:

//Game.h

class Game{
     std::vector<Player<Game>*> players;
}

//Player.h

template <typename T>
class Player{
     std::vector<Card<T>> hand;
}

//Card.h
template <typename T>
class Card {
    virtual void playCard(T& game);
}
V Mircan
  • 203
  • 5
  • 13
  • Well because it seems not to link properly. I am trying to get out of a class interdependence loop and i came up with this workaround of making the second class template so that it didn't need to include the first one. – V Mircan Nov 28 '18 at 22:14
  • 2
    Highly related: https://stackoverflow.com/questions/31345193/how-can-an-incomplete-type-be-used-as-a-template-parameter-to-vector-here Retracted as a dupe as I'm not sure if general support was added. – NathanOliver Nov 28 '18 at 22:14
  • 4
    You need to show your minimal code for help. – drescherjm Nov 28 '18 at 22:14
  • 3
    If you have a link error and that's relevant to your question, you need to add the error message to your question, along with anything else that is relevant. – paddy Nov 28 '18 at 22:21

1 Answers1

2

When std::vector<Player<Game>*> players; is parsed, Game's definition is not yet complete. Therefore Game will be considered incomplete type until its is. Then T=Game in Player and Card are also incomplete at their respective instantiation.

This is not a problem in itself. Incomplete types may be used, but there is a list of situation in which their use is prohibited (see https://en.cppreference.com/w/cpp/language/type#Incomplete_type for a reference list).

From your definition for Player and Card it doesn't seem like it requires a complete type for T, however this is highly dependent on the code you left out, e.g. if either of them have a data member of type T or type dependent on T, then there might be a problem.

There is also the question of whether std::vector can accept an incomplete type as template argument. Before C++17 this was not allowed, since C++17 it is allowed at least in the declaration (but not for access to its members). In any case, given your code Card<T> at std::vector<Card<T>> hand; instantiated with T=Game is complete and so the vector is not an issue.

(The way the code was posted, there is also an issue in the template declaration order which I did not address as I have knowledge of the include order and forward-declarations)