std::is_trivially_copyable 是编译期类型特征,用于判断类型是否可安全用 memcpy 拷贝;需满足:特殊成员函数平凡或已删除、无虚函数/虚基类、所有成员及基类均可平凡拷贝、内存布局连续无歧义。

std::is_trivially_copyable 是 C++ 标准库中一个编译期类型特征(type trait),用于在编译时判断某个类型是否“可平凡拷贝”——即它的对象能否安全地用 memcpy 进行字节级拷贝,而不会导致未定义行为或逻辑错误。
它检查的四个核心条件
一个类型 T 被判定为 std::is_trivially_copyable_v,必须同时满足:
- 所有特殊成员函数(拷贝构造、移动构造、拷贝赋值、移动赋值、析构)都是“平凡的”(由编译器隐式生成,未被用户显式定义或 =default 以外的方式声明),或被显式删除(
= delete); - 类型不含虚函数,也不继承自虚基类;
- 所有非静态数据成员和直接基类本身也都是
trivially copyable; - 对象的内存布局是连续、无歧义的字节序列(例如,没有因对齐填充导致的“逻辑间隙”干扰位拷贝语义)。
为什么这个特性重要
它不是语法装饰,而是高性能底层操作的“安全开关”:
- 允许编译器对拷贝/赋值做
memcpy级别优化(比逐成员调用构造函数快得多); - 支撑
std::bit_cast(C++20)的合法使用前提; - 是实现内存重定位(如 realloc-style 对象迁移)、序列化到 raw buffer、跨线程共享 POD-like 数据的基础保障;
- 很多标准容器(如
std::vector)对trivially copyable元素会启用更激进的内存操作路径。
常见类型判断示例
以下代码在编译期就能得出确定结果:
立即学习“C++免费学习笔记(深入)”;
-
int、float、std::array→true; - 空结构体
struct S {}或仅含int成员的struct A { int x; };→true; - 含用户定义拷贝构造函数的
struct B { B(const B&) {} int x; };→false; - 带虚函数的类、含
std::string或std::vector成员的类 →false; - 即使只加一个
const int x = 42;(带 brace-or-equal-initializer),也可能破坏 trivially copyable(取决于是否触发隐式非平凡行为,C++17 起更严格)。
和 std::is_trivial 的区别
std::is_trivial 要求更严:它不仅要求 trivially copyable,还额外要求有平凡的默认构造函数(即不能有用户提供的默认构造,也不能有带默认初始化器的非静态成员)。所以:
- 所有
trivial类型一定是trivially copyable; - 但
trivially copyable不一定trivial(比如一个只有int成员、但显式写了MyClass() = default;的类,仍是trivially copyable,且通常是trivial;但如果加了int x{0};,就可能失去trivial,但未必失去trivially copyable)。










