2013-12-18 6 views
5

Я делаю текстовую приключенческую игру на C++. Это структура для объекта в этой игре (что-то пользователь может подобрать и положить в инвентарь)C++ struct с шаблоном в векторе

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

Примеры объектов:

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." }; 

Множественные имена являются синонимами команды парсер , поэтому пользователь может ввести «взять книгу» или «забрать книгу рецептов», которая в обоих случаях поднимает объектную книгу.

Теперь я хотел бы создать векторный инвентарь для хранения всех элементов в инвентаре.

vector<Object> inventory; 

Теперь, с курса, это дает мне ошибку компилятора, потому что он ожидает что-то вроде этого:

vector<Object<5>> inventory; 

Однако, некоторые объекты имеют больше имен, чем другие, это что-то вроде этого возможно и если так как?

vector<Object<N>> inventory; 
+7

почему вы должны держать N в качестве шаблона? , если N отличается от другого, вы можете использовать 'std :: vector names' вместо' string names [N] ' – Raxvan

+3

Кажется, сегодня существует одержимость написанием ответов в комментариях! –

ответ

11

Все ваши различные Object<N> классы различных типов с различными размерами. Вы не можете разместить их в однородном контейнере .

Вам понадобится базовый класс или базовый интерфейс, а также сохранить указатели в векторе, опираясь на виртуальную отправку и полиморфизм, когда вы вытащите элементы. Это сделало бы ваш контейнер Object s a гетерогенным контейнером.

В качестве альтернативы и, предпочтительно, падения шаблона и сохранить имен в контейнере члена:

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

vector<Object> easy; 

PS. Я не считаю Object хорошим именем для любого класса. Предложение CompuChip от InventoryItem имеет больше смысла.

+1

+1 для альтернативного решения, которое я считаю лучшим. И для замечания об использовании 'Object' в качестве имени класса. Могу ли я предложить что-то описательное, например 'InventoryItem'? – CompuChip

+0

@CompuChip: Мне нравится ваше предложение. –

+0

@CompuChip 'object' на самом деле довольно описателен в играх, подобных этому - элемент может также быть в комнате или использоваться как оборудование, или как скрытая дверь и т. Д. –

0

A vector должен знать размер объектов, которые он содержит, поэтому, очевидно, он не может допускать различные экземпляры шаблонов внутри (sizeof(Object<N+X>) > sizeof(Object<N>)).

Снимите шаблонный массив из главного Object структуры, и заменить его с общим vector или list или string объектов вместо этого, и ваша проблема решена.

0

Выведите Объект из BaseObject и образуют вектор интеллектуальных указателей на 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); 
Смежные вопросы