如何实现带最小尺寸限制的std::vector派生容器?
实现带最小尺寸限制的std::vector子类
可以不用重写所有构造函数、迭代器及绝大多数方法,只需针对性覆盖初始化相关构造函数和元素移除类方法,就能满足你的需求。核心思路是利用继承复用std::vector的大部分功能,仅对涉及最小尺寸约束的逻辑做修改。
1. 强制初始化至少包含1个元素
无需重写所有构造函数,只需覆盖几个关键构造入口,在基类构造完成后(或构造时)确保容器尺寸不小于1:
#include <vector> #include <algorithm> template <typename T> class MinSizeVector : public std::vector<T> { public: // 无参构造:直接初始化1个默认元素 MinSizeVector() : std::vector<T>(1) {} // 带初始大小的构造:若传入大小<1则强制为1 explicit MinSizeVector(size_t n) : std::vector<T>(std::max(n, size_t(1))) {} // 带初始大小和值的构造:同样强制最小尺寸为1 MinSizeVector(size_t n, const T& val) : std::vector<T>(std::max(n, size_t(1)), val) {} // 迭代器范围构造:若传入范围为空则添加1个默认元素 template <typename InputIt> MinSizeVector(InputIt first, InputIt last) : std::vector<T>(first, last) { if (this->empty()) { this->push_back(T()); } } // 初始化列表构造:若列表为空则添加1个默认元素 MinSizeVector(std::initializer_list<T> il) : std::vector<T>(il) { if (this->empty()) { this->push_back(T()); } }
2. 禁止移除最后剩余的元素
仅需覆盖涉及元素移除的核心方法,确保操作后容器尺寸始终≥1:
// 覆盖pop_back:仅当元素数量>1时执行移除 void pop_back() { if (this->size() > 1) { std::vector<T>::pop_back(); } } // 覆盖单元素erase:若要删除的是最后一个元素则不执行 typename std::vector<T>::iterator erase(typename std::vector<T>::iterator pos) { if (this->size() > 1) { return std::vector<T>::erase(pos); } return pos; // 返回原迭代器,不做修改 } // 覆盖范围erase:确保删除后至少保留1个元素 typename std::vector<T>::iterator erase(typename std::vector<T>::iterator first, typename std::vector<T>::iterator last) { const size_t remove_count = std::distance(first, last); if (this->size() - remove_count >= 1) { return std::vector<T>::erase(first, last); } else { // 仅删除到剩余1个元素 return std::vector<T>::erase(this->begin(), this->begin() + (this->size() - 1)); } } // 覆盖clear:仅保留1个元素而非清空 void clear() { this->resize(1); } // 可选:覆盖resize,确保调整后的尺寸不小于1 void resize(size_t n) { std::vector<T>::resize(std::max(n, size_t(1))); } void resize(size_t n, const T& val) { std::vector<T>::resize(std::max(n, size_t(1)), val); } };
为什么无需重写所有内容?
std::vector的绝大多数方法(如push_back、insert、迭代器访问、size、capacity等)都可以直接继承复用,这些方法不影响最小尺寸约束- 仅需针对初始化逻辑和元素移除逻辑这两个核心需求做修改,其他功能完全依赖基类实现
- 迭代器无需重写,基类迭代器可以正常工作——因为我们保证容器始终非空,不会出现迭代器失效的异常场景
内容的提问来源于stack exchange,提问作者traveh
相关产品推荐
相关产品推荐

