Stephen Hansen
Stephen Hansen

Reputation: 25

C++11 Simple Singleton Template Function... or not?

So, I'm fairly new to serious C++, especially templates. But I'm trying to get deeper into it. I need a couple singletons (I know why these are considered sometimes bad), and was thinking of the easiest way to do them.

I settled on:

template <class T>
T& Singleton() {
    static T _instance;
    return _instance;
}

Now, something is obviously wrong with this and I'm missing it completely, because when I call "auto config = Singleton<Config>()" and set the configuration, later when I do it again in another part of code, the values are the default values.

I'm just not sure what is wrong.

My understanding is C++11 made it so static initialization is thread-safe, so a lot of the more complicated recipes aren't needed.

I thought the template would basically make a 'Singleton<Foo>()' function for every class passed to the template, and since in that function its making a static instance, every subsequent call to Singleton() would return the same instance.

Except its not doing so. So I'm missing something. Why is this seemingly obvious and easy way to accomplish something wrong? I'm assuming I'm missing out on something easy.

Note: I don't care to enforce singleton-ness. I'll only access the singletons through the function so its sufficient I always get the same instance back, it doesn't matter to me that I could bypass it and instantiate the singletons directly if I wanted to (in fact, that might be useful in certain circumstances). So I'm not going for the heavy-handed standard singleton method that makes single-instance everywhere absolute.

Upvotes: 0

Views: 172

Answers (1)

Rakete1111
Rakete1111

Reputation: 48998

template <class T>
T& Singleton() {
    static T _instance;
    return _instance;
}

Singleton() returns a reference, right, so you can modify the static variable. Everything is fine, but when you get the singleton, the variable also has to a reference, because if it's not, it can't take a reference and it will take a copy instead.

You're doing it like this: auto config = Singleton<Config>();. Notice how config isn't a reference, so it will just create a copy, so you get a different Singleton every time. Change config to be a reference: auto& config = Singleton<Config>();

Upvotes: 1

Related Questions