Search code examples
c++templatesshared-ptr

C++ - "Unspecialised class template" error with shared_ptr


I have a class Room and it holds a vector of shared_ptrs to Option objects like so:

private:
vector<shared_ptr<Option> > options;

But for some reason when I build, I get the following errors:

  • 'shared_ptr' : unspecialized class template can't be used as a template argument for template parameter '_Ty', expected a real type
  • 'std::tr1::shared_ptr' : use of class template requires template argument list

Strangely, I also have a vector of shared_ptrs, exact same syntax but there's no problem with that one.

There's also a bunch of places that bring up the error "'Option': undeclared identifier", which brings me to think it might be a problem with the Option class, but it seems to be fine. Here's the code for Option:

Option.h:

#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();
};

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

Solution

  • There is a bit of conjecture in this answer since you haven't posted the code for the Room class. I'm assuming this code

    private:
    vector<shared_ptr<Option> > options;
    

    is in Room.h. Your Option.h file includes Room.h, hence the Room class gets declared before the Option class. So Option is an incomplete type when the Room class' destructor is compiled and the shared_ptr implementation tries to delete the Option object.

    From the code above, I don't see why Option.h needs to include Room.h, in fact, it should be the other way around. If it does indeed need to include the file, you should be able to work around the problem by explicitly declaring Room::~Room() out-of-line in Room.cpp.

    EDIT:
    Turns out ~shared_ptr<T> does not require T to be a complete type. However, shared_ptr<T>( T* ) and shared_ptr<T>::reset( T* ) do, and the problem may be because some operation on the vector is invoking a call to one of these (more likely the former).