#include <iostream>
#include <memory>
#include <type_traits>
template<typename T, typename Deleter = std::default_delete<T>>
struct transitive_ptr : private std::unique_ptr<T, Deleter> {
using base_type = std::unique_ptr<T, Deleter>;
using typename base_type::element_type;
using typename base_type::deleter_type;
using typename base_type::pointer;
using const_pointer = typename std::add_pointer<typename std::add_const<typename std::remove_pointer<pointer>::type>::type>::type;
using reference = typename std::add_lvalue_reference<element_type>::type;
using const_reference = typename std::add_lvalue_reference<typename std::add_const<element_type>::type>::type;
using base_type::unique_ptr;
pointer get() { return base_type::get(); }
const_pointer get() const { return base_type::get(); }
reference operator*() { return *get(); }
const_reference operator*() const { return *get(); }
pointer operator->() { return get(); }
const_pointer operator->() const { return get(); }
};
template<typename T, typename... Args>
transitive_ptr<T> make_transitive(Args&&... args) {
return {std::make_unique<T>(std::forward<Args>(args)...)};
}
struct foo {
int x;
};
struct bar {
bar() : p{make_transitive<foo>()} {}
auto set_zero() /* const */ { p->x = 0; }
transitive_ptr<foo> p;
};
int main()
{
auto b = std::make_unique<bar>();
b->set_zero();
std::cout << b->p->x << std::endl;
return 0;
}