std::is_trivially_copyable 用于判断类型能否用 memcpy 安全复制,即跳过构造/析构直接按字节拷贝;需同时满足:平凡的特殊成员函数、无虚函数/虚基类、所有成员和基类也满足该特性。

std::is_trivially_copyable 用来判断类型能否用 memcpy 安全复制
它不是“能不能拷贝”,而是“能不能跳过构造/析构、直接按字节搬内存”。这是底层优化和 ABI 兼容的关键依据。比如你写 memcpy(dst, src, sizeof(T)),编译器不会帮你检查 T 是否允许这么干——std::is_trivially_copyable_v<t></t> 就是那个手动校验开关。
哪些类型会返回 true?看三个硬性条件
必须同时满足:有平凡的拷贝/移动/赋值/析构函数;不能有虚函数或虚基类;所有非静态成员和基类也都满足 trivially copyable。常见反例:
- 带
std::string成员的 struct → false(std::string析构要释放堆内存) - 含
virtual函数的 class → false(vptr 不可简单复制) - 有用户定义的拷贝构造函数(哪怕函数体为空)→ false(不再“平凡”)
-
struct Point { int x, y; };→ true(纯数据,无任何自定义行为)
别把它和 std::is_pod 混用,C++17 后已过时
std::is_pod 要求更严(还强制要求是“标准布局”+“平凡类型”),而 std::is_trivially_copyable 只关心“能不能 memcpy”,适用面更广。例如:
struct S {
int a;
private: int b; // 非标准布局(访问控制破坏 layout)
};
static_assert(std::is_trivially_copyable_v<S>); // ✅ 通过
static_assert(!std::is_pod_v<S>); // ❌ 失败
如果你只打算做内存拷贝(比如序列化到 buffer、GPU 传输、共享内存写入),std::is_trivially_copyable 才是正确守门员。
立即学习“C++免费学习笔记(深入)”;
实际使用时最常踩的坑:模板推导 + 继承链隐式破坏
模板里用 std::is_trivially_copyable_v<t></t> 做 if constexpr 分支很常见,但要注意:
- 派生类哪怕没加任何新成员,只要继承了带虚函数的基类,就自动变成 non-trivially-copyable
- 引用类型、数组类型、cv 限定符会影响结果:
std::is_trivially_copyable_v<int></int>是 false,std::is_trivially_copyable_v<const int></const>是 true - 注意
std::is_trivially_copyable对不完整类型(如前置声明的 class)返回 false,不是编译错误,但容易误判
真正难的从来不是查这个 trait,而是确保整个类型体系从根开始就没悄悄引入虚函数、非平凡成员或自定义操作符——这些改动往往藏在第三方头文件或深层基类里,一不小心就让 memcpy 崩溃在运行时。









