我想要一个类似数组的固定大小的对象,当新数据进入时它会循环并覆盖数据。我已经定义了这个模板类:
template <typename T, int N>
class CircularArray {
private:
T data[N];
std::size_t head = 0;
public:
std::size_t size() const {
return N;
}
T operator [](std::size_t i) const {
std::size_t j = (i + head) % N;
return data[j];
};
T & operator [](std::size_t i) {
std::size_t j = (i + head) % N;
return data[j];
};
void push(T val) {
data[head] = val;
head = (head + 1) % N;
}
};
这个想法很简单。索引 0 处的元素是最旧的元素,索引 N-1 处的元素是最新元素。这对于我想要的效果没问题,但我希望它的行为像
std::array
。有没有一种简单的方法来扩展 std::array
以获得这种循环行为?
编辑:我的意思是我希望拥有
std::array
的所有额外功能,而不必从头开始显式定义它。例如,拥有一个迭代器,允许我使用此类对象编写 C++17 风格的 for 循环。
对于这种类型的场景,您可能希望使用组合而不是继承。考虑以下几点。
#include <array>
#include <algorithm>
#include <iostream>
template <typename T, std::size_t N>
class ArrayWrap {
std::array<T, N> &arr;
public:
ArrayWrap(std::array<T, N> &arr) : arr(arr) {}
T operator[](std::size_t i) const {
return arr[i % N];
}
T& operator[](std::size_t i) {
return arr[i % N];
}
using iterator = typename std::array<T, N>::iterator;
iterator begin() {
return arr.begin();
}
iterator end() {
return arr.end();
}
};
int main() {
std::array<int, 4> a { 1, 2, 3, 4 };
ArrayWrap<int, 4> b(a);
std::cout << b[6] << std::endl;
for (auto x : b) {
std::cout << x << std::endl;
}
}
输出:
3
1
2
3
4
另请注意使用
std::size_t
而不是 int
。