必须同时提供const和非const版本的operator[],编译器根据对象是否const自动选择;非const版返回T&支持赋值,const版返回const T&仅支持读取,边界检查应复用,proxy仅用于特殊语义场景。
![c++重载下标运算符[]怎么区分只读和修改](https://img.php.cn/upload/article/001/221/864/179101110165757.png)
const 版本和非 const 版本必须同时提供
只读访问和修改访问的区分,不是靠参数或返回值类型单独决定的,而是靠 operator[] 成员函数是否带 const 限定符。编译器根据调用对象是否为 const,自动选择匹配的重载版本。不提供 const 版本时,const Array a; 就没法写 a[0] —— 即使你只想读,也会编译失败。
常见错误现象:
- 对 const 对象调用
[]报错:error: no matching function for call to 'Array::operator[](int) const' - 只写了 const 版本,却想给元素赋值:
a[0] = 42;编译不过,提示“assignment of read-only location”
返回引用类型是支持赋值的关键
非 const 版本必须返回 T&(如 int&),否则 arr[i] = x; 无法成立——只有可修改的左值才能出现在赋值号左边。const 版本则应返回 const T&,既避免拷贝开销,又阻止意外修改。
使用场景差异:
立即学习“C++免费学习笔记(深入)”;
-
int& operator[](int i):用于非常量对象,支持读写,比如arr[2] = 100;或int x = arr[2]; -
const int& operator[](int i) const:用于 const 对象或临时对象,仅支持读,比如const Array& ref = get_array(); int y = ref[3];
注意:返回值类型不能是 int(纯值),否则 arr[i] = x 会变成对临时量赋值,编译直接拒绝。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
边界检查逻辑要复用,别写两遍
两个版本的函数体通常只差在返回值,下标合法性校验(比如越界抛异常)应该完全一致。硬写两套逻辑不仅易错,还违反 DRY 原则。
实操建议:
- 把检查逻辑抽成私有成员函数,比如
void check_bounds(int i) const;,两个operator[]都调它 - 或者用 const 版本实现核心逻辑,非 const 版本转调 const 版本再 const_cast(慎用,仅当底层数据确实可变且无副作用时)
- 避免在 const 版本里做非常量操作(如 lazy 初始化、统计访问次数),那会破坏 const 正确性
proxy 返回值适用于特殊语义,但别滥用
如果容器语义复杂(比如稀疏数组、位级访问、只读视图),直接返回 T& 不够用,就得用代理类(proxy)。例如 BitArray[5] 返回一个能隐式转 bool 又支持 = 的临时对象。
但要注意:
- proxy 会抑制 RVO,增加一次构造/析构开销
- 它让
auto x = arr[i];得到的是 proxy 类型,不是原始类型,可能引发意料外的隐式转换 - 普通连续内存容器(如封装
std::vector或裸指针)完全不需要 proxy;强行上反而掩盖了设计意图
真正需要 proxy 的地方,往往连 const 和非 const 的区分都得在 proxy 内部处理,而不是靠两个 operator[]。

















