William Black
William Black

Reputation: 63

C++ struct with template in vector

I'm making a text adventure game in C++. This is the struct for an object in that game (something the user can pick up and put in the inventory)

template <int N>
struct Object
{
    static const int length = N;
    string names[N];
    string description;
};

Examples of objects:

Object<2> flower = { {"flower", "the flower"}, "A strange looking flower"};
Object<3> book = { { "the book", "book", "recipe book" }, "The world's finest cocktail recipes now all in one easy to use companion." };

The multiple names are synonyms for the command parser, so the user can input "pick up book" or "pick up recipe book", which in both cases picks up the object book.

Now I'd like to create a vector inventory to store all the elements in the inventory.

vector<Object> inventory;

Now, off course, this gives me a compiler error, because it expects something like this:

vector<Object<5>> inventory;

However, some objects have more names than others, is something like this possible and if so, how?

vector<Object<N>> inventory;

Upvotes: 6

Views: 322

Answers (3)

Charles Pehlivanian
Charles Pehlivanian

Reputation: 2133

Derive Object from BaseObject, and form a vector of smart pointers to BaseObject:

struct BaseObject
{
   virtual ~BaseObject() = default;
};

template<int N>
  struct Object : public BaseObject
{
   static const int length = N;
   string names[N];
   string description;
};

typedef shared_ptr<BaseObject> Objptr;
vector<Objptr> Inventory(1006);

Upvotes: 0

Niels Keurentjes
Niels Keurentjes

Reputation: 41968

A vector needs to know the size of the objects it contains, so obviously it cannot allow varying template instances inside (sizeof(Object<N+X>) > sizeof(Object<N>)).

Remove the templated array from the main Object struct, and replace it with a common vector or list or string objects instead, and your problem is solved.

Upvotes: 0

Lightness Races in Orbit
Lightness Races in Orbit

Reputation: 385405

All your different Object<N> classes are different types with different sizes. You can't put them in a homogenous container.

You would need some base class or base interface, and store pointers in the vector, relying on virtual dispatch and polymorphism when you pull the elements out. This would make your container of Objects a heterogenous container.

Alternatively, and preferably, drop the template and store the names in a member container:

struct Object
{
    set<string> names;
    string description;
};

vector<Object> easy;

PS. I don't consider Object to be a good name for any class. CompuChip's suggestion of InventoryItem makes more sense.

Upvotes: 12

Related Questions