【问题标题】:move-only input and output iterators只移动输入和输出迭代器
【发布时间】:2016-02-06 16:26:10
【问题描述】:

关于InputIterator/OutputIterator-s 将其语义修改为仅移动是否一致?当然,我的意思只是新创建的自定义迭代器,而不是 STL 的。

++i++r 输入和输出迭代器表达式的语义要求的注释相应地表示:

后置条件:i 的先前值的任何副本不再需要可取消引用或位于 == 的域中。

在此操作之后,r 不需要是可递增的,并且 r 的先前值的任何副本都不再需要是可取消引用或可递增的。

我认为在大多数情况下禁止拥有输入/输出迭代器的副本更安全,但从未听过这样的建议。这是个坏主意吗?

【问题讨论】:

  • 如果我有一台时间机器,让这些迭代器在 C++98 中只移动将是我的首选。使您的自定义输入/输出迭代器只移动是一个安全的实验。如果您尝试将它们与尝试复制它们的代码一起使用,您将在编译时收到警报,然后您可以检查这种情况。它甚至可能指出该通用代码中的错误。

标签: c++ c++11 iterator move


【解决方案1】:

在 C++20 中,新的迭代器概念 input_iteratoroutput_iterator 不需要可复制。 ranges 命名空间中的算法以及视图适配器也支持仅移动迭代器。

新视图ranges::istream_view 返回只移动迭代器以提高安全性。 最后,新的 C++20 view 概念本身不需要可复制性,它只允许移动自己的状态。

仍然可以创建不是copyablecopyable input_iteratoroutput_iterator,但我建议不要这样做。

forward_iterators 当然仍然必须是copyable。哨兵也需要copyable

您可以在以下论文中阅读有关该设计的矿石

【讨论】:

    【解决方案2】:

    输入/输出迭代器必须首先满足迭代器要求。这个要求说,从 C++14,[iterator.iterators],p2:

    A 类型 X 满足 Iterator 要求,如果:

    • X 满足 CopyConstructibleCopyAssignableDestructible 要求 (17.6.3.1)

    所以不,它们不能只移动。

    【讨论】:

    • 现在我明白了,但我觉得它们最初应该是只移动的(例如std::istream)。 Howard Hinnant 证实了我的考虑。
    • @Orient:不管我同意与否,你的问题是“可以做到吗”?答案是“不按标准”。 Ranges TS 同样要求它们是可复制的。
    【解决方案3】:

    这可能不是一个好主意。迭代器对象通常被设计为轻量级的,并且通过值传递以提高效率。许多 C++ 标准库容器使用按值传递的迭代器。禁用复制构造函数对我来说似乎不是一个好主意。

    例如参见http://www.cplusplus.com/reference/vector/vector/vector/,向量构造函数按值接受输入迭代器。

    请参阅http://www.cplusplus.com/reference/algorithm/copy/ 以获取按值接受输出迭代器的 C++ 标准库容器示例

    【讨论】:

    • 这根本不是问题:我可以使用 std::move 传递迭代器值。
    • 这将传递一个迭代器右值引用。你为什么要这样做?
    • 这仍然会有与之相关的开销。当迭代器更高效且需要更少的汇编代码复制时,为什么还要将它移动到另一个位置?
    • 我要禁止输入/输出迭代器的副本。
    • 没有为此目的引入移动语义。这就像说你应该将一个整数移动到另一个位置而不是复制它,因为它在未来不会在原始副本的上下文中再次使用
    猜你喜欢
    • 1970-01-01
    • 2012-02-10
    • 2023-01-03
    • 2022-11-14
    • 2021-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多