fork(9) download
  1. #include <iostream>
  2. #include <utility>
  3. #include <functional>
  4.  
  5. using namespace std;
  6.  
  7. template<typename T> // Singleton policy class
  8. class Singleton
  9. {
  10. protected:
  11. Singleton() = default;
  12. Singleton(const Singleton&) = delete;
  13. Singleton& operator=(const Singleton&) = delete;
  14. virtual ~Singleton() = default;
  15. public:
  16. template<typename... Args>
  17. static T& getInstance(Args... args) // Singleton
  18. {
  19. cout << "getInstance called" << std::endl;
  20.  
  21. //we pack our arguments in a T&() function...
  22. //the bind is there to avoid some gcc bug
  23. static auto onceFunction = std::bind( createInstanceInternal<Args...>, args... );
  24. //and we apply it once...
  25. return apply( onceFunction );
  26. }
  27.  
  28. private:
  29.  
  30. //single instance so the static reference should be initialized only once
  31. //so the function passed in is called only the first time
  32. static T& apply( const std::function<T&()>& function )
  33. {
  34. static T& instanceRef = function();
  35. return instanceRef;
  36. }
  37.  
  38. template<typename... Args>
  39. static T& createInstanceInternal(Args... args)
  40. {
  41. static T instance{ std::forward<Args>(args)... };
  42. return instance;
  43. }
  44.  
  45. };
  46.  
  47.  
  48. class Foo: public Singleton<Foo>
  49. {
  50. friend class Singleton<Foo>;
  51. Foo()
  52. {
  53. cout << "Constructing instance " << this <<" of Foo" << endl;
  54. }
  55. Foo(int x)
  56. {
  57. cout << "Constructing instance " << this <<" of Foo with argument x = "\
  58. << x << endl;
  59. }
  60.  
  61. ~Foo()
  62. {
  63. cout << "Destructing instance " << this << " of Foo" << endl;
  64. }
  65. };
  66.  
  67. int main()
  68. {
  69. // this should just return the instance
  70. // instead, it constructs another instance
  71. // because invokes an overloaded version of get_instance()
  72. Foo& rfoo1 = Foo::getInstance(1);
  73.  
  74. Foo& rfoo = Foo::getInstance(); // default constructible
  75.  
  76. // this is OK
  77. // calls the SAME overloaded version again, instance is static
  78. // so we get the same instance
  79. Foo& rfoo2 = Foo::getInstance(2);
  80. }
Success #stdin #stdout 0s 3476KB
stdin
Standard input is empty
stdout
getInstance called
Constructing instance 0x804adf0 of Foo with argument x = 1
getInstance called
getInstance called
Destructing instance 0x804adf0 of Foo