c++中原生数组不可整体赋值,因数组名非左值;应改用std::array实现拷贝赋值,或逐元素复制/ memcpy;结构体嵌数组可赋值是因结构体整体赋值触发成员逐复制。

为什么 arr = other_arr 会报错 assignment to expression with array type
这个错误说明你试图对一个原生数组(比如 int arr[5])直接赋值。C++ 不允许对数组类型做整体赋值——数组名不是左值,它退化为指针后更不能被赋值。编译器看到 arr = other_arr 就会拒绝,因为 arr 的类型是“具有数组类型的表达式”,而 C++ 标准禁止给这种表达式赋值。
用 std::array 替代原生数组实现可赋值
最干净的解法是改用 std::array,它是栈上分配、零开销的容器,支持拷贝赋值:
#include <array>
std::array<int> a = {1,2,3,4,5};
std::array<int> b;
b = a; // ✅ 合法,会逐元素拷贝</int></int></array>
-
std::array大小必须在编译期确定,和原生数组一样 - 成员函数如
.size()、.data()都可用,兼容性好 - 传参时建议用
const std::array<t>&</t>避免拷贝
如果必须用原生数组,只能逐元素复制或用 memcpy
原生数组不可赋值,但可以手动复制内容。注意:不能用 =,也不能用 std::copy 直接写到数组名(它不是指针变量):
int src[3] = {1,2,3};
int dst[3];
// ❌ 错误:dst = src;
// ✅ 正确:用循环
for (int i = 0; i )
memcpy(dst, src, sizeof(src));
-
memcpy快但不调用构造/析构函数,仅适用于 POD 类型 - 用
std::copy(src, src+3, dst)也可以,但要确保dst是可修改的左值(比如声明为普通数组变量,而非函数参数中的int arr[]形参) - 函数形参写成
void f(int arr[5])实际等价于void f(int* arr),此时arr是指针,不能sizeof(arr)得到数组长度
常见误判点:函数返回数组、结构体里嵌数组
有人以为写个函数返回数组就能绕过限制,但 C++ 不允许函数返回原生数组类型(语法错误)。结构体里嵌数组倒是可以赋值,因为结构体整体可赋值:
struct Wrap { int data[3]; };
Wrap a = {{1,2,3}}, b;
b = a; // ✅ 合法:结构体赋值触发成员数组的逐元素复制
- 这本质是编译器自动生成的逐成员复制,不是“数组赋值”
- 若结构体含非 POD 成员(如
std::string),仍能正常赋值,但原生数组部分仍是按位拷贝 - 别为了赋值强行包装结构体——优先选
std::array,语义清晰且无歧义
真正卡住人的地方往往不是“怎么复制”,而是没意识到原生数组名本身不可寻址为左值。哪怕加括号 (arr) 或取地址再解引 (*&arr) 都不能让它变成可赋值目标。改用 std::array 是最省心的路径;硬要留原生数组,就得接受手动复制的事实。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











