I am developing a relatively large library (~13000 lines) as a personal utility library. It uses exclusively STL containers and smart pointers for memory management - but now I find myself in a situation where I could see going for normal pointers due to an apparent lack of an obvious solution in STL. I would like to maintain a modern C++ style, though.
Here's my mcve:
Struct Foo - a int-wrapper struct displaying which member functions were called.
struct Foo {
    Foo(int x) {
        this->x = x;
        std::cout << "constructor\n";
    }
    Foo(const Foo& other) {
        this->x = other.x;
        std::cout << "copy constructor\n";
    }
    ~Foo() {
        std::cout << "destructor\n";
    }
    int x;
};
Looking at main I create an automatic instance of struct Foo:
int main() {
    Foo foo{ 0 };
    std::cout << "\nfoo.x : " << foo.x << "\n\n";    
}
output >
constructor
foo.x : 0
destructor
Easy as that. - now if I want to point to foo and manipulate its content. 
Smart pointers like std::unique_ptr or std::shared_ptr won't achieve this effect (apparently!). Using std::make_unique<T>() (/ std::make_shared<T>()) will dynamically allocate memory and only copy the value:
Foo foo{ 0 };
std::unique_ptr<Foo> ptr = std::make_unique<Foo>(foo);
ptr->x = 2;
std::cout << "\nptr->x : " << ptr->x << '\n';
std::cout << "foo.x  : " << foo.x << "\n\n";
output >
constructor
copy constructor
ptr->x : 2
foo.x  : 0 // didn't change  
destructor
destructor
So that's not working. However, their void reset(pointer _Ptr = pointer()) noexcept member function allows to directly assign a pointer: 
std::unique_ptr<Foo> ptr;
Foo foo{ 0 };
ptr.reset(&foo);
ptr->x = 2;
std::cout << "\nptr->x : " << ptr->x << '\n';
std::cout << "foo.x  : " << foo.x << "\n\n";
output >
constructor
ptr->x : 2
foo.x  : 2
destructor
destructor //crash
But crash! foo get's deconstructed normally and than std::shared_ptr also wants to deconstruct its already deconstructed dereferenced value. 
HEAP[main.exe]: Invalid address specified to RtlValidateHeap(...)
Using a const pointer:
Foo foo{ 0 };
Foo* const ptr = &foo;
ptr->x = 2;
std::cout << "\nptr->x : " << ptr->x << '\n';
std::cout << "foo.x  : " << foo.x << "\n\n";
output >
constructor
ptr->x : 2
foo.x  : 2
deconstructor
- 1 allocation, 1 deallocation.
- no copying.
- actually manipulating the value.
So far the pointer feels like the best option.
I am just looking for a way to point to automatically allocated objects. So far it seems surprisingly difficult without going back to plain pointers.
I provided one solution by myself - which is using /*const*/ std::reference_wrapper<T>. (feel free to correct me about this solution)
But I am not sure what's the best strategy. The pointer? the std::reference_wrapper maybe? Did I made a mistake with using std::shared_ptr / std::unique_ptr? 
Is there a better, more straightforward STL class?
 
     
    