Reputation: 589
First, please don't give me a lecture about "singletons are bad". I've read all about it and looked at the alternatives for the use case I have, and it is the best fit.
OK, I'm trying to create a convenient C++ singleton template based on what I know what and what I've read. I've got this far:
template <class T>
class Singleton{
protected:
Singleton(); // Disallow instantiation outside of the class.
public:
Singleton(const T&) = delete;
T& operator=(const T&) = delete;
Singleton(T &&) = delete;
T& operator=(T &&) = delete;
static auto& Instance(){
static T instance;
return instance;
}
};
class Derived : public Singleton<Derived> {
Derived() {}
friend class Singleton<Derived>;
};
main() {
auto derived = Derived::Instance();
}
When I compile I get the linker error:
undefined reference to `Singleton<Derived>::Singleton()'
.. and I don't understand why. I'm operating at the limits of my understanding of template programming.
I'd also like to avoid the need to create a constructor in the derived class and the friend class statement. I understand why it is needed, but I'd rather be able to use some template magic to create a default constructor for the Derived class within the Singleton template. I get that constructors can't be inherited, but thought that template magic might be able to at least create one automatically.
I think it is clear what I'm trying to do conceptually, so if there is an easier overall approach that would work, that would also be fine. The goal is to not have to write all the deleted operators and instance creation function for every different type of singleton I need to define.
Any help would be humbly accepted (as long as it isn't a singleton lecture :-)
Upvotes: 0
Views: 142
Reputation: 847
You have declared the default constructor for Singleton<T>
, but you haven't defined it anywhere. You can either provide a definition inline like this:
template <class T>
class Singleton{
protected:
Singleton() { /* definition goes here */ }
public:
// ...
};
or just default it if you don't need to do anything in particular in the constructor:
template <class T>
class Singleton{
protected:
Singleton() = default;
public:
// ...
};
Also, you can leave off the Derived
constructor if you're just going to leave it empty:
class Derived : public Singleton<Derived> {
// Derived() {} the compiler will generate this for you
friend class Singleton<Derived>;
};
Upvotes: 1
Reputation: 19213
Just a typo is happening - your constructor is missing its implementation
class Singleton{
protected:
Singleton()=default; // You probably meant this.
public:
//...
};
Upvotes: 1