gpt4 book ai didi

c++ - C++ 中的简单流迭代器

转载 作者:行者123 更新时间:2023-11-30 05:22:15 24 4
gpt4 key购买 nike

考虑一个类似 Java 的流式迭代器:

template<class V>
struct Iterator
{
V& next();
bool hasNext();
}

template<class V>
struct Iterable
{
Iterator<V> iterator();
}

如何将其转换为 std::iterator 以便可以在查找、for 循环等中使用它。

我想我需要从 InputIterator 开始,但我在这里遇到以下问题:

  • 有意义的结束()?
  • 它们什么时候相等()?
  • 距离呢?

最佳答案

这是非常可行的,但是很痛苦。

你最好做一个基于生成器的迭代器,其中支持操作是 std::function< optional<T> > .以下是此类生成器-迭代器的示例:

template<class T>
struct generator_iterator {
using difference_type=std::ptrdiff_t;
using value_type=T;
using pointer=T*;
using reference=T;
using iterator_category=std::input_iterator_tag;
std::optional<T> state;
std::function< std::optional<T>() > operation;
// we store the current element in "state" if we have one:
T operator*() const {
return *state;
}
// to advance, we invoke our operation. If it returns a nullopt
// we have reached the end:
generator_iterator& operator++() {
state = operation();
return *this;
}
generator_iterator operator++(int) {
auto r = *this;
++(*this);
return r;
}
// generator iterators are only equal if they are both in the "end" state:
friend bool operator==( generator_iterator const& lhs, generator_iterator const& rhs ) {
if (!lhs.state && !rhs.state) return true;
return false;
}
friend bool operator!=( generator_iterator const& lhs, generator_iterator const& rhs ) {
return !(lhs==rhs);
}
// We implicitly construct from a std::function with the right signature:
generator_iterator( std::function< std::optional<T>() > f ):operation(std::move(f))
{
if (operation)
state = operation();
}
// default all special member functions:
generator_iterator( generator_iterator && ) =default;
generator_iterator( generator_iterator const& ) =default;
generator_iterator& operator=( generator_iterator && ) =default;
generator_iterator& operator=( generator_iterator const& ) =default;
generator_iterator() =default;
};

使用类似 Java 的 iterface 仍然可以做到这一点。

boost 中会有解决方案这使这更容易。但我会根据 C++17 概念“原始”编写它,如果您需要它们(或从 boost 或其他来源中提取),可以将其反向移植到 C++11。

您将生成一个输入迭代器,因为这是类 Java 接口(interface)所支持的。

首先我会写一个助手。助手将持有 optional< Iterator<V> >和一个 optional<V> .

它将支持++。++ 会推进迭代器并将值读入 optional<V> .

它将支持一元 * . *将返回可选中的值。

bool is_end()如果 optional<Iterator<V>> 返回真是空的,或者如果它是!.hasNext() .

==当且仅当两个参数 .is_end() 返回真. !=只是!适用于== .

这个助手还不是迭代器,但它有大部分关键操作。

然后我们使用this poly_iterator哪种类型删除任何类似迭代器的东西。我们上面写的对 helper 的操作就足够了。

然后我们写一个函数接受Iterable<V>并产生 range<poly_iterator<T>>上面的类型删除类,使用上面的辅助伪迭代器。 range<It>是一个看起来像这样的类:

template<class It>
struct range {
It b; It e;
It begin() const { return b; }
It end() const { return e; }
};

也许还有其他实用程序助手。

如果您愿意,可以跳过类型删除步骤。只需将上面编写的帮助程序扩充为一个成熟的输入迭代器。 Boost 有一些助手可以让这更容易。让范围返回器返回那个成熟的输入迭代器。我碰巧有 poly_iterator<T>躺在另一个答案中,如果你有锤子,那问题肯定看起来像钉子。

请注意,为了让代码真正像 Java,我们希望实际拥有指向对象的(智能)指针而不是拷贝。

关于c++ - C++ 中的简单流迭代器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39729637/

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