std::polymorphic<T>, part of P3019R14 arriving in C++26, is a heap-allocated wrapper that owns an object whose dynamic type may be T or any derived type, and copies it via type-erased deep copy without slicing. It removes the need for virtual clone() methods and hand-written Rule of Five special member functions in classes holding polymorphic collections. Notably, the base class no longer needs a virtual destructor, since polymorphic tracks the dynamic type internally for destruction and copying. It lacks comparison operators, hash support, and perfect-forwarded assignment because the type is erased, and has no null state other than after a move (checked via valueless_after_move()). A comparison table explains when to prefer indirect, polymorphic, variant, or shared_ptr.

6m read timeFrom sandordargo.com
Post cover image
Table of contents
The clone() taxDropping the boilerplate with std::polymorphicDeep copies just workNo virtual destructor neededConst propagationWhat polymorphic does not provideThe valueless stateChoosing between indirect and polymorphicConclusionConnect deeper

Questions this post answers

What does std::polymorphic in C++26 do and how does it differ from std::indirect?

std::polymorphic<T>, part of proposal P3019R14 targeted for C++26, is a heap-allocated wrapper whose dynamic type may be T or any type derived from T, and copying it performs a type-erased deep copy that preserves the dynamic type. Unlike std::indirect<T>, which always stores exactly a T, polymorphic supports an open set of derived types without requiring a virtual clone() method. Track proposals like std::polymorphic as they land so upgrades to C++26 don't catch your codebase off guard, via daily.dev.

How can I have a copyable collection of polymorphic C++ objects without writing a virtual clone() method?

Using std::polymorphic<Shape> instead of std::unique_ptr<Shape> in a std::vector eliminates the need for clone() entirely, because the type-erasure machinery inside polymorphic knows the actual dynamic type and can copy or destroy it directly. This also means all special member functions of the owning class can be compiler-generated, removing the Rule of Five boilerplate. Developers weighing indirection strategies in C++ can follow patterns like this on daily.dev.

Does std::polymorphic require the base class to have a virtual destructor in C++26?

No, the base class destructor can be protected and non-virtual, because std::polymorphic uses type erasure for both destruction and copying and therefore knows the exact dynamic type, allowing it to call the correct destructor directly without vtable dispatch. This also prevents accidentally deleting a raw base pointer since nobody ever holds one. Stay ahead of subtle C++ design changes like this by following language evolution on daily.dev.

262 Impressions