C++ - ошибка шаблона неспециализированного класса с shared_ptr

У меня есть класс Room, и он содержит вектор shared_ptrs для объектов Option, например:

private:
vector<shared_ptr<Option> > options;

Но по какой-то причине, когда я строю, я получаю следующие ошибки:

  • 'shared_ptr': неспециализированный шаблон класса нельзя использовать в качестве аргумента шаблона для параметра шаблона '_Ty', ожидается реальный тип
  • 'std::tr1::shared_ptr': для использования шаблона класса требуется список аргументов шаблона.

Как ни странно, у меня также есть вектор shared_ptrs, точно такой же синтаксис, но с этим проблем нет.

Есть также куча мест, которые вызывают ошибку «'Option': необъявленный идентификатор», что заставляет меня думать, что это может быть проблема с классом Option, но, похоже, все в порядке. Вот код для опции:

Вариант.ч:

#pragma once
#include "Room.h"
#include <memory>

using namespace std;

class Option
{
protected:
    int id;
    char* text;

public:
    Option(void);
    Option(int, char*);
    virtual ~Option(void);
    char* getText();
    int getID();
};

Опция.cpp:

#include "Option.h"
#include "Room.h"
#include <memory>
using namespace std;

Option::Option(void)
{
}

Option::Option(int newID, char* newText){
    id = newID;
    text = newText;
}

Option::~Option(void)
{
}

char* Option::getText(){
    return text;
}

int Option::getID(){
    return id;
}

person Jean Finley    schedule 12.07.2012    source источник
comment
Пробовали ли вы vector‹std::tr1::shared_ptr‹Option› › options; ?   -  person marcinj    schedule 13.07.2012


Ответы (2)


В этом ответе есть небольшая догадка, поскольку вы не опубликовали код для класса Room. Я предполагаю этот код

private:
vector<shared_ptr<Option> > options;

находится в Room.h. Ваш файл Option.h включает Room.h, поэтому класс Room объявляется перед классом Option. Таким образом, Option является неполным типом, когда компилируется деструктор класса Room, а реализация shared_ptr пытается удалить объект Option.

Из приведенного выше кода я не понимаю, почему Option.h должен включать Room.h, на самом деле все должно быть наоборот. Если действительно необходимо включить файл, вы сможете обойти проблему, явно объявив Room::~Room() вне очереди в Room.cpp.

EDIT:
Оказывается, ~shared_ptr<T> не требует, чтобы T был полный тип. Однако shared_ptr<T>( T* ) и shared_ptr<T>::reset( T* ) работают, и проблема может заключаться в том, что некоторая операция над vector вызывает вызов одного из них (скорее всего, первого).

person Praetorian    schedule 12.07.2012
comment
ооо, я вижу, это имеет смысл. Мне нужна эталонная комната в опции, потому что у меня есть виртуальная shared_ptr‹Room› getRoom(); тоже, который переопределяется в подклассе RoomOption. Я объявил деструктор комнаты, который, по-видимому, не исправил его... - person Jean Finley; 13.07.2012
comment
Я нашел способ сослаться на комнату в Option, используя идентификатор int вместо фактической ссылки на комнату. Я все же хотел бы знать, почему деструктор не работает так, как вы предложили, если у вас есть понимание. - person Jean Finley; 13.07.2012
comment
@JeanFinley Кроме того, Option.h не нужно включать Room.h только потому, что в нем была объявлена ​​функция-член virtual shared_ptr<Room> getRoom();, просто объявите класс Room как class Room; вместо включая заголовок. Option.cpp, возможно, потребуется включить Room.h, но это нормально, поскольку, удалив его из заголовка, вы избавились от циклической зависимости. - person Praetorian; 13.07.2012
comment
Я закомментировал в Room все, что связано с Option (кроме самого вектора), и это все еще не работает. Я сейчас выложу код комнаты - person Jean Finley; 13.07.2012
comment
Форвардное объявление (о котором я только что узнал, когда вы его упомянули) сработало. Я должен тебе десять миллионов печенья. Спасибо! - person Jean Finley; 13.07.2012

vector<shared_ptr<Option >>

Вы почти сделали правильно :)

vector<shared_ptr<Option> >

Это два символа >, которые при касании вызывают странные ошибки, которые вы видите. Он интерпретируется как оператор >>.

Кстати, спасибо, что разместили свой код в точности как есть, а не ввели его обратно и, возможно, скрыли ошибку.

person Ed S.    schedule 12.07.2012
comment
Дох! Спасибо. Исправил, но у меня все та же проблема. Как ни странно, у меня также есть вектор shared_ptrs для объектов Item (тот же синтаксис, но с Item вместо Object), и он отлично работает... Кроме того, спасибо за то, что вы так милы ^_^ - person Jean Finley; 13.07.2012