Blog About

The missing C++ smart pointer

This article has been featured on the frontpage of Hacker News, the follow-up discussion is interesting to read.

After some years doing Rust and OCaml, coming back to C++ has made me realize that it lacks yet another smart pointer type, which would arguably be more general and less surprising than all the ones currently existing in the C++20 standard.

Inspired by Box<T> in Rust, the std::box<T> would be a heap-allocated smart pointer. The encapsulated object would be stored in dynamic memory (heap), with std::box<T> serving as an RAII wrapper managing the object's lifecycle. Upon going out of scope, std::box<T> would automatically delete the object it points to, thus preventing memory leaks.

However, it would fully embrace the essential C++ paradigm of value semantic (I know, value and pointer together sound weird): copying the pointer would copy the underling object, instead of sharing it like a shared_ptr or a raw pointer. This is the reason why it's not named XXX_ptr, it's a smart pointer which acts as a value.

Let's compare this hypothetical std::box<T> with other pointer types in C++, providing a clear perspective of the distinct advantages it could offer over each.

Pointer Type Value semantic Movable Copyable (Default) Garbage Collection Heap/Recursive
std::box Yes Yes Yes (Deep Copy) Yes Yes
Raw Value Yes Yes Yes (Deep Copy) Yes No
Raw Pointer No No ownership Yes (Shallow Copy) No Yes
std::shared_ptr No Yes Yes (Shallow Copy) Yes Yes
std::unique_ptr Yes Yes No Yes Yes
std::auto_ptr Weird Yes Transfer Ownership Yes Yes

This hypothetical std::box is nothing new: it's ubiquitous in Rust, and its the way any data type works in OCaml (on the surface at least). One of the reason for preventing its mass adoption might be the performance implication : the key characteristic of std::box<T> is its deep copy behavior which implies a full replication of the underlying object (it's actually similar to using a raw value, which also performs a deep copy operation when copied).

Let me know if any of this makes sense or if there is a better name for this (owned_ref<T>? owned<T>? unique_ptr_but_you_can_copy_me_baby<T>?)