对 std::array 的循环扩展

问题描述 投票:0回答:1

我想要一个类似数组的固定大小的对象,当新数据进入时它会循环并覆盖数据。我已经定义了这个模板类:

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 循环。

c++ arrays stl
1个回答
0
投票

对于这种类型的场景,您可能希望使用组合而不是继承。考虑以下几点。

#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

© www.soinside.com 2019 - 2024. All rights reserved.