如何为std::array实现边界检查?重载operator[]遇左值错误求解
如何给继承std::array的自定义类实现带边界检查的operator[]
嘿,你碰到的这个lvalue required错误,根源大概率是你的operator[]返回的是值类型而非引用类型——这样它就没法作为赋值操作的左操作数啦。当然可以给std::array的派生类实现带边界检查的operator[],咱们直接上解决方案和思路:
错误原因分析
你原来的operator[]可能是类似这样写的(推测):
array_datatype operator[](unsigned int index) { assert(index < array_size); return std::array<array_datatype, array_size>::operator[](index); }
这种写法返回的是元素的副本,不是原元素的引用,执行array[0] = 911时相当于给临时副本赋值,编译器自然会报错说需要左值。
正确实现方案
要解决问题,咱们需要实现两个版本的operator[]:非const版本返回可修改的引用,const版本返回只读的const引用,同时在逻辑里加上边界检查:
#include <array> #include <cassert> #include <iostream> #include <stdexcept> // 如果用异常代替断言需要包含这个头文件 template <unsigned int array_size, typename array_datatype = long int> struct Array : public std::array<array_datatype, array_size> { // 非const版本:返回可修改引用,支持赋值操作 array_datatype& operator[](unsigned int index) { // 用断言做调试阶段检查,Release模式可关闭 assert(index < array_size && "Array index out of bounds!"); // 如果需要Release模式也保留检查,替换成抛出异常: // if (index >= array_size) { // throw std::out_of_range("Array index out of bounds!"); // } return std::array<array_datatype, array_size>::operator[](index); } // const版本:返回只读引用,适配const对象的调用 const array_datatype& operator[](unsigned int index) const { assert(index < array_size && "Array index out of bounds!"); return std::array<array_datatype, array_size>::operator[](index); } }; // 测试代码 int main() { Array<5> myArray; myArray[0] = 911; // 现在可以正常赋值啦 std::cout << myArray[0] << std::endl; // 输出911 // 下面这行代码会触发断言(调试模式)或抛出异常(若替换为异常逻辑) // myArray[10] = 123; const Array<3> constArray; std::cout << constArray[0] << std::endl; // const对象可正常调用const版本operator[] // constArray[0] = 456; // 这行会报错,符合const语义 return 0; }
关键要点说明
- 非const版本返回
array_datatype&:直接返回容器内元素的引用,允许赋值操作,完美解决左值问题。 - const版本返回
const array_datatype&:保证const对象调用operator[]时只能读取元素,符合C++的const正确性原则。 - 边界检查可选:用
assert适合调试阶段快速发现问题,用std::out_of_range异常则适合在Release模式下保留错误处理逻辑。
内容的提问来源于stack exchange,提问作者Evandro Coan
相关产品推荐
相关产品推荐

