

新闻资讯
技术教程std::is_trivially_copyable 用于判断类型能否安全用 memcpy,要求所有成员和基类均为平凡可复制、无用户定义拷贝/移动函数、无虚函数或虚基类、析构函数为默认或删除;含 std::string 等非平凡类型则必为 false;即使为 true,仍需确保对齐、生命周期与内存权限合法。
memcpy
它返回 true,仅当类型满足:
所有非静态成员和基类都是 trivially copyable;没有用户定义的拷贝/移动构造函数、赋值运算符;没有虚函数或虚基类;析构函数是默认或删除的。满足这些,才代表该类型的对象内存布局是“平坦”的,memcpy 不会跳过指针、不触发逻辑、不破坏内部状态。
即使结构体只有两个 int 和一个 std::string,std::is_trivially_copyable_v 一定是 false。因为 std::string 内部有指针、容量、大小等字段,且其拷贝必须调用构造函数来管理堆内存 —— 直接 memcpy 会导致浅拷贝、双重释放或悬垂指针。
std::shared_ptr、std::function,基本都不可 trivially copyablestruct {})或纯 POD 结构(如 struct { int x; double y; })通常是 true
constexpr 构造函数但没用户定义拷贝函数,不影响 trivially copyable 判定即使 std::is_trivially_copyable_v 是 true,也不能无条件用 memcpy。比如:
memcpy 会复制垃圾值(虽不崩溃,但可能影响 memcmp 或序列化一致性)alignas(16) 类型 memcpy 到 char* 数组起始处),会触发未定义行为const_cast 绕过的只读内存页上,memcpy 可能 SIGSEGVstruct alignas(16) Vec4 { float x, y, z, w; };
static_assert(std::is_trivially_copyable_v); // ✅
Vec4 a = {1,2,3,4}, b;
memcpy(&b, &a, sizeof(Vec4)); // ❌ 若 &b 未按 16 字节对齐,UB
= default 拷贝,而非 memcpy现代 C++ 中,99% 的场景下,编译器对 T a = b; 或 std::copy 的优化程度和 memcpy 一样高,且语义安全。只有在极少数底层场景(如 ring buffer 批量搬运、与 C ABI 交互、GPU 显存映射)才需手动 memcpy,此时必须同时检查:
std::is_trivially_copyable_v 为 true
std::is_standard_layout_v(保证内存布局可预测,避免基类偏移问题)alignof(T) 对齐要求漏掉其中任一条件,就不是“能 memcpy”,而是“正在制造难以复现的崩溃”。