On Wed, Oct 29, 2025 at 11:11 AM Frederick Virchanza Gotham via Std-Proposals <std-proposals@lists.isocpp.org> wrote:

I'm saying that there are four different classifications when it comes to a type's relocatability:

(Type 1)  Cannot be relocated
(Type 2)  Can be relocated by a simple memcpy
(Type 3)  Can be relocated by an algorithm built into the compiler
(Type 4)  Can be relocated by a custom-implemented relocator algorithm provided by the author of the class

So, on arm64e when you relocate a simple polymorphic object, you get Type 3. (Whereas on every other compiler it's only Type 2).

Type 4 would be the likes of std::string in short-string optimisation mode.

libstdc++'s std::string is Type 4.
libc++'s and MSVC's std::string are Type 2.
See https://quuxplusone.github.io/blog/2019/02/20/p1144-what-types-are-relocatable/ .

Notice that in Type 4, the "custom-implemented algorithm" can actually be a generic algorithm: to relocate an object, all you have to do is move-construct it and destroy it. These are of course type-specific operations — T::T(T&&) and T::~T() for some specific T.

The benefit of Type 2 is that you can do it without any knowledge of what T is. This means you can use Type 2 types with type-erased, C-style "algorithms" such as:
- realloc (which "relocates" all the elements in the reallocated buffer by relocating their bytes)
- qsort (which shuffles elements by relocating their bytes)
- the internals of std::function and std::move_only_function (which, in order to be efficiently movable, want to "relocate" the contained object without knowing its type — this means they want to contain only objects that are Type 2)

Your Type 3 is very fuzzy. Consider that any algorithm can be "built into the compiler"; there's nothing particularly special about polymorphic objects here. For example: libstdc++ and libc++ both have non-Type-2 std::list. Relocating their std::list requires updating pointer fields in the head and tail nodes. This operation is easily codegennable by the compiler — in fact std::list is constexpr in C++26; none of its methods are allowed to be opaque to the compiler — and this operation cannot possibly fail at runtime. Therefore, arguably, lib{std,}c++'s std::list (with the default allocator) ought to be considered Type 3, not Type 4.

There's a very clear physical delineation between Type 1, Type 2, and "all the rest."  The line between Type 3 and Type 4 is not physical but linguistic, and arbitrary.

–Arthur