fork download
  1. #include <iostream>
  2. #include <memory>
  3. #include <type_traits>
  4.  
  5. template<typename T, typename Deleter = std::default_delete<T>>
  6. struct transitive_ptr : private std::unique_ptr<T, Deleter> {
  7. using base_type = std::unique_ptr<T, Deleter>;
  8. using typename base_type::element_type;
  9. using typename base_type::deleter_type;
  10. using typename base_type::pointer;
  11. using const_pointer = typename std::add_pointer<typename std::add_const<typename std::remove_pointer<pointer>::type>::type>::type;
  12. using reference = typename std::add_lvalue_reference<element_type>::type;
  13. using const_reference = typename std::add_lvalue_reference<typename std::add_const<element_type>::type>::type;
  14.  
  15. using base_type::unique_ptr;
  16.  
  17. pointer get() { return base_type::get(); }
  18. const_pointer get() const { return base_type::get(); }
  19.  
  20. reference operator*() { return *get(); }
  21. const_reference operator*() const { return *get(); }
  22.  
  23. pointer operator->() { return get(); }
  24. const_pointer operator->() const { return get(); }
  25. };
  26.  
  27. template<typename T, typename... Args>
  28. transitive_ptr<T> make_transitive(Args&&... args) {
  29. return {std::make_unique<T>(std::forward<Args>(args)...)};
  30. }
  31.  
  32. struct foo {
  33. int x;
  34. };
  35.  
  36. struct bar {
  37. bar() : p{make_transitive<foo>()} {}
  38. auto set_zero() /* const */ { p->x = 0; }
  39. transitive_ptr<foo> p;
  40. };
  41.  
  42. int main()
  43. {
  44. auto b = std::make_unique<bar>();
  45. b->set_zero();
  46. std::cout << b->p->x << std::endl;
  47. return 0;
  48. }
  49.  
  50.  
Success #stdin #stdout 0s 3228KB
stdin
Standard input is empty
stdout
0