fork(1) download
  1. #include <iostream>
  2. #include <memory>
  3.  
  4. class any_ptr
  5. {
  6. struct WrapperBase
  7. {
  8. virtual ~WrapperBase(){}
  9. };
  10.  
  11. template<typename T>
  12. struct Wrapper : WrapperBase, T
  13. {
  14. template<typename ... Args>
  15. Wrapper( Args&&... args ):
  16. T( std::forward<Args>(args)... ) {}
  17. };
  18.  
  19. std::unique_ptr<WrapperBase> mPtr;
  20.  
  21. any_ptr( std::unique_ptr<WrapperBase> ptr ):
  22. mPtr{ std::move(ptr) } {}
  23.  
  24. public:
  25.  
  26. template< typename T >
  27. explicit operator T*()
  28. {
  29. return dynamic_cast<T*>(mPtr.get());
  30. }
  31.  
  32. template< typename T >
  33. explicit operator T const*() const
  34. {
  35. return dynamic_cast<T*>(mPtr.get());
  36. }
  37.  
  38. template<typename T>
  39. friend any_ptr make_any_ptr( T&& t )
  40. {
  41. return std::unique_ptr<WrapperBase>{ new Wrapper<T>{ std::forward<T>(t) } };
  42. }
  43.  
  44. template< typename T,
  45. typename ... Args >
  46. friend any_ptr make_any_ptr( Args&&... args )
  47. {
  48. return std::unique_ptr<WrapperBase>{ new Wrapper<T>{ std::forward<Args>(args)... } };
  49. }
  50. };
  51.  
  52. ////////////////////////////////////////////////////////////////////////////////
  53.  
  54. template <class T>
  55. bool inspect(any_ptr& p, void (&fun)(T))
  56. {
  57. using actual_t = typename std::remove_reference<T>::type;
  58.  
  59. if( actual_t* t = static_cast<actual_t*>(p) )
  60. fun(*t);
  61.  
  62. return false;
  63. }
  64.  
  65. ////////////////////////////////////////////////////////////////////////////////
  66.  
  67. class printable
  68. {
  69. public:
  70. virtual void print() const = 0;
  71. };
  72.  
  73. ////////////////////////////////////////////////////////////////////////////////
  74.  
  75. #include <string>
  76. using namespace std;
  77.  
  78. class foo : public printable
  79. {
  80. public:
  81. foo(string const& s) : m_s(s) {}
  82.  
  83. virtual void print() const
  84. {
  85. cout << "foo: " << m_s << "\n";
  86. }
  87.  
  88. private:
  89. string m_s;
  90. };
  91.  
  92. class bar : public printable
  93. {
  94. public:
  95. bar(int i) : m_i(i) {}
  96.  
  97. virtual void print() const
  98. {
  99. cout << "bar: " << m_i << "\n";
  100. }
  101.  
  102. private:
  103. int m_i;
  104. };
  105.  
  106. ////////////////////////////////////////////////////////////////////////////////
  107.  
  108. void print_printable(printable& p)
  109. {
  110. p.print();
  111. }
  112.  
  113. ////////////////////////////////////////////////////////////////////////////////
  114.  
  115. int main()
  116. {
  117. auto f = make_any_ptr(foo("foo"));
  118. auto b = make_any_ptr(bar(42));
  119.  
  120. inspect(f, print_printable);
  121. inspect(b, print_printable);
  122. }
Success #stdin #stdout 0s 3476KB
stdin
Standard input is empty
stdout
foo: foo
bar: 42