如何为MappedVector类重载间接寻址运算符以匹配下标行为?
MappedVector类的指针式访问运算符重载实现
问题描述
需要实现一个类MappedVector:
- 元素唯一,重复添加无效,行为类似
std::set - 元素按自定义顺序排列而非自动排序,行为类似
std::vector - 已通过
std::vector+std::map实现核心功能,现在需要添加运算符重载,让*(obj + 1)等价于obj[1]
当前遇到的问题:
- 尝试重载间接寻址运算符时只能访问首个元素
- 若返回
*get()会触发编译错误:Error C2676 binary '+': 'MAPPED_VECTOR' does not define this operator or a conversion to a type acceptable to the predefined operator - 需要在不影响类内vector状态的前提下完成重载
原因分析
编译错误的核心是:obj + 1是对MappedVector对象执行加法操作,但该类未重载operator+,也没有可转换为支持加法的类型(比如指针)的隐式转换。同时原get()方法返回的是vector的副本,即便能转换,也会导致额外拷贝且无法正确关联原对象的元素。
解决方案
要实现*(obj + n)等价于obj[n],需要完成两个关键步骤:
- 重载
operator+,让它接受偏移量并返回指向对应位置元素的指针 - 利用指针本身的
operator*完成解引用,无需额外重载间接寻址运算符
同时优化原有方法的效率:将get()改为返回vector的引用而非副本,operator[]返回元素的引用而非值拷贝。
完整代码示例
#include <vector> #include <stdexcept> #include <map> #include <functional> template <typename ValueType, typename Comparer = std::less<ValueType>> class MappedVector { public: using VECTOR = std::vector<ValueType>; using MapType = std::map<ValueType, size_t, Comparer>; private: VECTOR _vector = {}; MapType _indexMap = {}; // 用于保证元素唯一性的映射 public: // 返回vector的引用而非副本,避免不必要拷贝 const VECTOR& get() const { return _vector; } VECTOR& get() { return _vector; } // 重载下标运算符,返回元素引用,符合vector的行为 ValueType& operator[](ptrdiff_t index) { if (index < 0 || static_cast<size_t>(index) >= _vector.size()) { throw std::out_of_range("MappedVector index out of range"); } return _vector[index]; } const ValueType& operator[](ptrdiff_t index) const { if (index < 0 || static_cast<size_t>(index) >= _vector.size()) { throw std::out_of_range("MappedVector index out of range"); } return _vector[index]; } // 重载operator+,返回指向对应元素的指针 ValueType* operator+(ptrdiff_t offset) { if (offset < 0 || static_cast<size_t>(offset) >= _vector.size()) { throw std::out_of_range("MappedVector offset out of range"); } return &_vector[offset]; } // const版本的operator+,支持const对象使用 const ValueType* operator+(ptrdiff_t offset) const { if (offset < 0 || static_cast<size_t>(offset) >= _vector.size()) { throw std::out_of_range("MappedVector offset out of range"); } return &_vector[offset]; } // 核心方法:添加元素并保证唯一性 bool add(const ValueType& value) { if (_indexMap.contains(value)) { return false; // 元素已存在,添加失败 } _indexMap[value] = _vector.size(); _vector.push_back(value); return true; } }; // 使用示例 #include <iostream> int main() { MappedVector<int> mv; mv.add(3); mv.add(1); mv.add(2); // 测试下标访问 std::cout << mv[1] << std::endl; // 输出1 // 测试*(obj + n) std::cout << *(mv + 1) << std::endl; // 输出1 std::cout << *(mv + 2) << std::endl; // 输出2 // const对象测试 const MappedVector<int>& constMv = mv; std::cout << *(constMv + 0) << std::endl; // 输出3 return 0; }
说明
operator+返回的是指向内部vector元素的指针,既保证了*(obj + n)的行为符合预期,又不会暴露整个vector的内部状态- 同时实现了非const和const版本的运算符,保证const对象也能正常使用该功能
- 添加了越界检查,抛出
std::out_of_range异常,行为与标准库容器保持一致 add方法示例展示了如何利用map保证元素唯一性,符合类的设计需求
内容的提问来源于stack exchange,提问作者tomysshadow
相关产品推荐
相关产品推荐

