fork download
  1. #include <type_traits>
  2. #include <memory>
  3. #include <iostream>
  4.  
  5. namespace detail
  6. {
  7. template <typename T>
  8. struct wrapper
  9. {
  10. virtual ~wrapper() {}
  11. virtual T const * get() const = 0;
  12. virtual T * get() = 0;
  13. };
  14.  
  15. template <typename T, typename F>
  16. struct storage
  17. : wrapper<T>
  18. {
  19. storage(F f)
  20. {
  21. p_ = f();
  22. }
  23.  
  24. T const * get() const { return p_.get(); }
  25. T * get() { return p_.get(); }
  26.  
  27. private:
  28. typename std::result_of<F()>::type p_;
  29. };
  30. }
  31.  
  32. template <typename T>
  33. class some_class
  34. {
  35. public:
  36. template <typename F>
  37. void store(F f)
  38. {
  39. storage_.reset(new detail::storage<T, F>(f));
  40. }
  41.  
  42. T const * get() const { return storage_->get(); }
  43. T * get() { return storage_->get(); }
  44.  
  45. private:
  46. std::unique_ptr<detail::wrapper<T>> storage_;
  47. };
  48.  
  49. struct foo
  50. {
  51. void bar() const { std::cout << "hello" << '\n'; }
  52. };
  53.  
  54. int main()
  55. {
  56. some_class<foo> a;
  57. a.store([]() { return std::unique_ptr<foo>(new foo()); });
  58. a.get()->bar();
  59. a.store([]() { return std::unique_ptr<
  60. foo, std::default_delete<foo[]>
  61. >(new foo[1], std::default_delete<foo[]>()); });
  62. a.get()[0].bar();
  63.  
  64. return 0;
  65. }
Success #stdin #stdout 0s 3476KB
stdin
Standard input is empty
stdout
hello
hello