gpt4 book ai didi

c++ - 自定义容器上的C++ “periodic”迭代器

转载 作者:行者123 更新时间:2023-12-02 09:47:57 24 4
gpt4 key购买 nike

我有一个包含特定类元素 vector 的类。主要思想是根据序列的一个周期(elems_)和周期数(nperiod_)生成元素的周期性序列,因此我不需要存储所有元素,而只需存储一个周期。

class PeriodicContainer
{
private:
std::vector<Class> elems_; // elements
size_t nperiod_; // period of repetition of elems_
public:
PeriodicContainer();
PeriodicContainer(const std::vector<Class>& elems, size_t nperiod);
/*...*/
}
是否可以为 PeriodicContainer实现自定义迭代器,以便我可以做(半伪代码)之类的事情:
PeriodicContainer container({Class(1), Class(2)}, 4);
for (auto it : container)
std::cout << it << '\n';
和输出将是
Class(1)
Class(2)
Class(1)
Class(2)
Class(1)
Class(2)
Class(1)
Class(2)

最佳答案

如果您的基础容器只是一个std::vector,那么您知道它是一个连续的容器-实际上,这非常容易。
您可以通过以下方式形成迭代器:

  • 指向要迭代的容器的指针(或引用),以及
  • 当前的迭代计数(注意:不是'index')。包装在容器的operator[]之后,将用作基础容器的size()的“索引”。

  • 该迭代器的行为将很简单:
  • 每个增量仅增加当前计数
  • 每个取消引用都返回(*elems_)[current_ % elems_->size()],它将解决“期间”的循环问题。
  • begin()会简单地返回一个带有0计数的迭代器,以及
  • end()将返回一个带有elems_.size() * nperiod_计数的迭代器

  • 下面是 LegacyForwardIterator 的示例:

    template <typename T>
    class PeriodicContainerIterator
    {
    public:
    using value_type = T;
    using reference = T&;
    using pointer = T*;
    using difference_type = std::ptrdiff_t;
    using iterator_category = std::forward_iterator_tag;

    PeriodicContainerIterator(std::vector<T>* elems, std::size_t current)
    : elems_{elems},
    current_{current}
    {}

    reference operator*() {
    return (*elems_)[current_ % elems_->size()]
    }
    pointer operator->() {
    return &(*elems_)[current_ % elems_->size()];
    }
    PeriodicContainerIterator& operator++() const {
    ++current_;
    return (*this);
    }
    PeriodicContainerIterator operator++(int) const {
    auto copy = (*this);
    ++current_;
    return copy;
    }

    bool operator==(const PeriodicContainerIterator& other) const {
    return current_ == other.current_;
    }
    bool operator!=(const PeriodicContainerIterator& other) const {
    return current_ != other.current_;
    }

    private:
    std::vector<T>* elems_;
    std::size_t current_;
    };
    然后,容器将 begin()end()定义为:

    PeriodicContainerIterator<Class> begin() {
    return PeriodicContainerIterator<Class>{&elems_, 0};
    }
    PeriodicContainerIterator<Class> end() {
    return PeriodicContainerIterator<Class>{&elems_, elems_->size() * nperiod_};
    }
    您可以很容易地将其一直扩展到 LegacyRandomAccessIterator ,但这需要大量额外的功能,这些功能会使该答案变得很庞大。

    如果您不是特别需要将其用作迭代器,而只是想以一种简单的方式来访问周期序列中的每个元素,则如果将其放入类似于 for_each的调用并希望进行回调的调用中,则可能会更容易阅读/理解。代替。例如:
    template <typename Fn>
    void forEach(Fn&& fn)
    {
    for (auto i = 0; i < nperiod_; ++i) {
    for (auto& e : elems_) {
    fn(e);
    }
    }
    }
    允许像这样使用:
    container.forEach([&](auto& e){
    // 'e' is each visited element
    });

    关于c++ - 自定义容器上的C++ “periodic”迭代器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63475839/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com