LANGUAGES Signal 421
C++26 adds std::indirect for value semantics with heap-allocated objects
Illustration only Photo by Hunter Haley on Unsplash
std::indirect in C++26 provides deep-copyable, const-propagating ownership of dynamically allocated objects for composite classes
Engineers writing value-semantic C++ classes with heap-allocated members can now avoid manual Rule of Five implementations. The new type enforces const-correctness and deep-copy semantics automatically, reducing boilerplate and potential bugs in composite types.
Written by elseif from the cluster below · every claim links back to a sourceThe three things worth knowing
std::indirect enables deep copying of heap-allocated members without manual copy constructors
Const propagation works as expected, preventing mutation through const access paths
Value-based comparison and hashing are supported when the owned type provides them
THE READ
What the cluster adds up to.
C++26 introduces std::indirect as a vocabulary type in <memory> that addresses two long-standing pain points with std::unique_ptr in composite classes. The first is const propagation: unique_ptr's const operator*() returns a non-const reference, allowing mutation of owned objects through const access paths. std::indirect fixes this by returning a const reference when accessed through a const path, making const-correctness violations compile-time errors rather than runtime surprises.
The second pain point is copy semantics. unique_ptr deletes copy operations, forcing developers to implement all five special member functions manually when they want value semantics. std::indirect provides deep-copy semantics out of the box, copying the owned object when the containing object is copied. This eliminates the Rule of Five boilerplate while maintaining value semantics for composite types with heap-allocated members.
std::indirect also provides value-based comparison and hashing when the owned type supports these operations. This means two indirect<T> objects compare equal if their owned T objects compare equal, rather than comparing pointer addresses. The type is designed specifically for use as a class member, where value semantics are typically desired, rather than for ownership transfer between functions like unique_ptr.
The implementation requires the owned type to be copyable, as deep copies are fundamental to its operation. This makes it unsuitable for move-only types or types with expensive copy operations. The type also doesn't support custom deleters, as its focus is on providing value semantics rather than flexible resource management. These limitations are intentional trade-offs for the specific use case of composite class members.
Written by elseif from the cluster below · checked for specifics the sources never containedTHE CLUSTER