#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;
}

