繁体   English   中英

符合标准的 transform_iterator

[英]Standard-conforming transform_iterator

我的目标是拥有一个迭代器来迭代T类型的元素,但在我的情况下, T对于我的最终用户来说并不是真正可用的。 相反,最终用户应该使用具有更有用接口的包装器W

为了构造一个W ,我们需要一个T加上一个指向附加数据结构的引用或指针。

问题是我永远不会将元素存储为W 相反,元素总是存储为T并且只按需包装。 因此,我的用户必须迭代包含T的数据结构。

我的想法是为这些数据结构编写一个自定义迭代器,它本身迭代存储的T ,但在取消引用时将返回W 我开始研究如何实现这一点,并找到了有关该主题的各种信息,包括如何处理迭代器的reference typedef 实际上不是引用。 这包括在这种情况下实现operator->arrow_proxy技巧。

然而,我也试图阅读标准以了解它对此类迭代器的看法。 我的资源在 这里,它清楚地指出,一旦我们处理前向迭代器, reference就应该是对value_type的(const)引用。 这个问题支持这一点。

这让我想知道是否有可能合理地实现这样一个transform_iterator ,如果打算将其用作forward_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 ,但我无法完全理解它们实际应用于这些类型的迭代器的迭代器类别的实现。 然而, 他们似乎确实将类别基于所提供的 function 的结果类型(以某种方式),这表明至少在他们的实现中类别可能与input_iterator_tag不同(尽管可能是唯一的其他选项是output_iterator_tag ?)。

注 2:上面链接的问题也提出了我在此处勾画的相同解决方法。 这是否表明没有更好的方法?


TL;DR:有没有比在迭代器本身中存储该类型的成员并在每次取消引用时更新该成员更好的方法来实现例如将取消引用时的迭代类型转换为不同类型的前向迭代器?

首先,选择你可以摆脱的最严格的迭代器类别:

  • 如果您不需要允许多次通过,请使用InputIterator并按值返回一个临时W

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

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

    正如您所说,这只能通过将W存储在某处(在迭代器中或放在一边)来完成。

    最大的问题是可变的前向迭代器:如果i == j ,改变*i也必须影响*j ,这意味着你的W不能是独立的值类型,而必须是某种直写代理。 这并非不可能,但您不能简单地采用某些现有类型并像这样使用它。

如果您具有 C++20 访问权限,则仅使用transform_view可能会节省一些精力——尽管将其他所有内容更改为使用范围而不是原始迭代器的工作可能会抵消这方面的工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM