#include <iostream>
#include <utility>
#include <functional>
using namespace std;
template<typename T> // Singleton policy class
class Singleton
{
protected:
Singleton() = default;
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
virtual ~Singleton() = default;
public:
template<typename... Args>
static T& getInstance(Args... args) // Singleton
{
cout << "getInstance called" << std::endl;
//we pack our arguments in a T&() function...
//the bind is there to avoid some gcc bug
static auto onceFunction = std::bind( createInstanceInternal<Args...>, args... );
//and we apply it once...
return apply( onceFunction );
}
private:
//single instance so the static reference should be initialized only once
//so the function passed in is called only the first time
static T& apply( const std::function<T&()>& function )
{
static T& instanceRef = function();
return instanceRef;
}
template<typename... Args>
static T& createInstanceInternal(Args... args)
{
static T instance{ std::forward<Args>(args)... };
return instance;
}
};
class Foo: public Singleton<Foo>
{
friend class Singleton<Foo>;
Foo()
{
cout << "Constructing instance " << this <<" of Foo" << endl;
}
Foo(int x)
{
cout << "Constructing instance " << this <<" of Foo with argument x = "\
<< x << endl;
}
~Foo()
{
cout << "Destructing instance " << this << " of Foo" << endl;
}
};
int main()
{
// this should just return the instance
// instead, it constructs another instance
// because invokes an overloaded version of get_instance()
Foo& rfoo1 = Foo::getInstance(1);
Foo& rfoo = Foo::getInstance(); // default constructible
// this is OK
// calls the SAME overloaded version again, instance is static
// so we get the same instance
Foo& rfoo2 = Foo::getInstance(2);
}