operator[]必须返回引用以支持赋值,非const版返回T&,const版返回const T&;需检查下标越界,标准库中operator[]不检查而at()抛异常,实现时应根据性能与安全需求权衡。
![c++如何实现运算符重载[]](https://img.php.cn/upload/article/001/221/864/178417390642777.png)
operator[] 必须返回引用才能支持赋值
直接返回值会导致 a[0] = 1 编译失败,因为右值不能被赋值。必须返回 T&(或 const T& 用于 const 对象),否则连基本的写入操作都不可用。
- 非 const 版本返回
T&,允许修改元素; - const 版本返回
const T&,防止意外修改; - 两个版本都要实现,否则 const 对象调用
operator[]会匹配不到函数; - 如果内部存储是裸指针(如
T* data_),记得检查下标越界,否则运行时崩溃风险极高。
下标越界处理:抛异常还是静默?
标准库容器(如 std::vector)的 at() 抛 std::out_of_range,而 operator[] 不检查——这是有意为之的性能取舍。你自己实现时得明确设计意图:
- 追求性能且调用方可信 → 直接访问,不检查(像内置数组);
- 需要安全兜底 → 在 debug 模式下用
assert(index ,或统一抛 <code>std::out_of_range; - 避免抛异常但又想诊断 → 返回一个代理对象(proxy),在赋值/读取时再检查(较重,一般不用);
- 注意:抛异常会中断控制流,若在析构函数或 noexcept 函数里调用,可能引发
std::terminate。
返回 proxy 而不是引用的典型场景
当元素访问涉及位级操作、压缩存储或延迟计算时(比如 std::vector<bool></bool>),直接返回 bool& 不合法(位域不能取地址),就必须用 proxy 类封装。
- proxy 需重载
operator=和类型转换(如operator bool()); - proxy 对象生命周期短,不能返回局部 proxy 的引用;
- proxy 增加间接层,影响内联和性能,仅在必要时采用;
- 示例常见于自定义 bitset、sparse array 或内存映射结构。
const 和 non-const 版本必须成对出现
漏掉 const 版本最常导致 “no match for operator[]” 错误,尤其在 const 成员函数里调用或传入 const 对象时。
立即学习“C++免费学习笔记(深入)”;
- 声明要严格对应:
T& operator[](size_t i);const T& operator[](size_t i) const; - 不能只靠参数重载区分,
const是函数签名一部分; - 内部逻辑通常复用,把非 const 版本转调 const 版本再 const_cast(不推荐),或提取公共私有函数;
- 返回类型不一致(比如一个返回
T*,一个返回const T*)会导致编译失败。
真正麻烦的是 proxy 设计和 const 正确性平衡——稍不留神,const 对象就能被改,或者 operator[] 根本无法在 const 上下文中使用。


















