Template parameter type has following requirements: - Is not polymorphic - Has no non-static data members of reference type - Satisfies Destructible requirement: https://en.cppreference.com/w/cpp/named_req/Destructible - All non-static data members and base classes follow the same requirements Even if all of the above requirements are met, type representation may vary depending on ABI and compiler optimizations (as stated in [class.mem]: "the order of allocation of non-static data members with different access control is unspecified"). To enforce the same layout for all ABIs and optimization levels type should satisfy StandardLayoutType requirement. If pointer is used with array type, additional requirement is: - Element type must be default constructible The pointer is not designed to work with polymorphic types, as they have runtime RTTI info embedded, which is implementation specific and thus not consistently rebuildable. Such constructs as polymorphic members or members of a union defined within a class held in a pointer will also yield undefined behavior. C++ standard states that lifetime of an object is a runtime property [basic.lifetime]. Conditions which must be fulfilled for object's lifetime to begin, imply that using any non-trivially constructible object with pointer is undefined behaviour. This is being partially addressed by the following proposal: https://groups.google.com/a/isocpp.org/forum/#!topic/std-proposals/bk8esqk-Qoo Another caveat is that snapshotting elements in a transaction and performing rollback uses memcpy internally. Using memcpy on an object in C++ is allowed by the standard only if the type satisfies TriviallyCopyable requirement.