C++新版本是否支持区分operator[]的读取与写入操作?
C++中区分operator[]读写操作的最新特性
截至C++23标准,并没有新增像Python里__setitem__/__getitem__那样能直接区分operator[]读、写操作的原生特性,传统的const/非const重载依然是最基础的实现方式:
- 非const重载:
T& operator[](unsigned int index)
当调用者是非const对象时触发,不管后续是读还是写,都会进入这个重载——因为返回的是可修改引用,无法在重载层面直接区分后续操作类型。如果要记录写入,只能通过额外手段实现。 - const重载:
const T& operator[](unsigned int index) const
调用者是const对象时触发,此时只能是读取操作,可以直接在这里执行读取记录逻辑。
如果需要精准区分非const对象下的读、写操作,目前主流的技巧是用代理对象替代直接返回引用:让非const版本的operator[]返回一个代理类实例,通过重载代理类的operator=(处理写入)和operator T(处理读取),分别在两个重载中执行对应的记录工作。示例代码如下:
#include <unordered_map> template<typename T> class MapProxy { private: std::unordered_map<unsigned int, T>& inner_map; unsigned int key; public: MapProxy(std::unordered_map<unsigned int, T>& map, unsigned int idx) : inner_map(map), key(idx) {} // 捕捉写入操作,执行记录逻辑 MapProxy& operator=(const T& val) { // 这里添加写入记录代码 inner_map[key] = val; return *this; } // 捕捉读取操作,执行记录逻辑 operator T() const { // 这里添加读取记录代码 return inner_map.at(key); } }; template<typename T> class MyMapWrapper { private: std::unordered_map<unsigned int, T> data; public: // const对象的读取操作 const T& operator[](unsigned int idx) const { // 添加读取记录代码 return data.at(idx); } // 非const对象的读写操作,返回代理 MapProxy<T> operator[](unsigned int idx) { return MapProxy<T>(data, idx); } };
这个方案能精准区分非const实例下的读、写行为,分别执行对应的记录逻辑,解决了传统重载无法区分读写的痛点。
内容的提问来源于stack exchange,提问作者masher
相关产品推荐
相关产品推荐

