c++ 符合标准的转换迭代器

gopyfrb3  于 2023-01-14  发布在  其他
关注(0)|答案(1)|浏览(128)

我的目标是有一个迭代器,它可以迭代T类型的元素,但是在我的例子中,T对于我的最终用户来说并不是真正有用的,相反,最终用户应该使用一个 Package 器W,它有一个更有用的接口。
为了构造一个W,我们需要一个T加上一个指向其他数据结构的引用或指针。
问题是我永远不会将元素存储为W,相反,元素总是存储为T,并且只在需要时才进行 Package ,因此,我的用户必须迭代一个包含T的数据结构。
我的想法是为这些数据结构编写一个自定义迭代器,它本身迭代存储的T,但在解引用时将返回W。我开始研究如何实现这一点,并找到了关于这个主题的各种信息,包括如何处理迭代器的reference typedef实际上不是一个引用。这包括在这种情况下实现operator->arrow_proxy技巧。
然而,我也尝试阅读标准,看看它对这样的迭代器有什么要说的,我的参考资料在这里和那里清楚地说明,只要我们处理前向迭代器,reference就应该是对value_type的(常量)引用,这是this question所支持的。
这让我想知道,如果有人打算将forward_iterator或更高版本用作forward_iterator,是否有可能合理地实现这样一个仍然符合标准的transform_iterator
我可以想到的一种方法是将迭代器的value_type声明为W,然后保留一个W类型的成员变量,这样operator*就可以像这样实现:

class transform_iterator {
    value_type = W;
    reference = W &;
    // ...

    reference operator*() const {
        m_wrapper = W(< obtain current T >, m_struct);
        return m_wrapper;
    }

    mutable W m_wrapper;
    SeparateDataStructure m_truct;
};

然而,这种方法对我来说似乎相当笨拙,除此之外,这似乎会大大增加迭代器的大小,这可能是一个问题,也可能不是一个问题(从长远来看)。
注1:我知道Boost.iterator提供了transform_iterator,但是我不能完全理解它们实际应用于这些类型的迭代器的迭代器类别。(以某种方式),这将暗示至少在它们的实现中该类别可能不同于input_iterator_tag(尽管可能唯一的其他选择是output_iterator_tag?)。
注2:question linked above也提出了与我在此概述的相同的解决方案,这是否表明没有更好的方法?
TL; DR:有没有更好的方法来实现,比如说,一个前向迭代器,它在解引用时将迭代的类型转换为一个不同的类型,而不是将该类型的成员存储在迭代器本身中,并在每次解引用时更新该成员?

rslzwgfq

rslzwgfq1#

首先,选择限制性最强的迭代器类别:

  • 如果您不需要允许多次传递,请使用InputIterator并只按值返回临时的W

它仍然具有所有常用的迭代器方法(operator*operator->operator++等)。

  • 如果确实需要多次传递,则需要一个ForwardIterator及其返回实际引用的附加要求。

正如您所说的,这只能通过在某处存储W来实现(在迭代器中或在一旁)。
最大的问题是可变的前向迭代器:如果i == j,那么*i的变化也会影响到*j,这意味着你的W不能是一个独立的值类型,而必须是某种写通代理,这不是不可能的,但是你不能简单地用一些现有的类型,然后像这样使用它。
如果你有C++20的访问权限,你可能会通过使用transform_view来保存一些工作--尽管这可能会被改变其他所有东西来使用范围而不是原始迭代器所带来的工作所抵消。

相关问题