代码之家  ›  专栏  ›  技术社区  ›  Георгий Гуминов

标准中是否提到std::copy_n源增量计数?

  •  0
  • Георгий Гуминов  · 技术社区  · 2 年前

    我已经实现了一个迭代器的例子,它对每个增量进行计数:

    #include <vector>
    #include <iostream>
    #include <algorithm>
    #include <iterator>
    
    template <class IteratorCategory = std::vector<int>::iterator::iterator_category>
    class DereferenceCountingIterator : public std::vector<int>::iterator {
      public:
        using iterator_category = IteratorCategory;
      public:
        static std::size_t increaseCnt;
    
        DereferenceCountingIterator(
            typename std::vector<int>::iterator iter)
                : std::vector<int>::iterator(iter) {}
    
        auto& operator++() {
          ++increaseCnt;
          return std::vector<int>::iterator::operator++();
        }
    
        DereferenceCountingIterator<IteratorCategory> operator+(difference_type diff) {
            return static_cast<std::vector<int>::iterator&>(*this).operator+(diff);
        }
    };
    

    此模板类既可以用作RandomAccess,也可以用作Input迭代器:

    
    template<class IteratorCategory>
    std::size_t DereferenceCountingIterator<IteratorCategory>::increaseCnt = 0;
    
    using RandomAccessDereferenceContingIterator = DereferenceCountingIterator<>;
    using NonRandomAccessDereferenceContingIterator
        = DereferenceCountingIterator<std::input_iterator_tag>;
    
    

    带有示例的应用程序:

    
    int main() {
        auto vec = std::vector<int>{3, 4, 5};
    
        auto rAVecBegin = RandomAccessDereferenceContingIterator(vec.begin());
        auto nonRAVecBegin = NonRandomAccessDereferenceContingIterator(vec.begin());
    
        {
            const auto incBefore = RandomAccessDereferenceContingIterator::increaseCnt;
            auto out = std::vector<int>{};
            std::copy_n(rAVecBegin, 3, std::back_inserter(out));
            const auto incAfter = RandomAccessDereferenceContingIterator::increaseCnt;
            std::cout << incAfter - incBefore << std::endl;
        }
    
        {
            const auto incBefore = NonRandomAccessDereferenceContingIterator::increaseCnt;
            auto out = std::vector<int>{};
            std::copy_n(nonRAVecBegin, 3, std::back_inserter(out));
            const auto incAfter = NonRandomAccessDereferenceContingIterator::increaseCnt;
            std::cout << incAfter - incBefore << std::endl;
        }
    
    
        return 0;
    }
    

    该程序的输出如下(两者都在 libstdc++ libc++ ):

    3
    2
    

    我能确定吗 copy_n 确实 n-1 如果源迭代器不是RandomAccessIterator并且 n 增量(如果是)?

    1 回复  |  直到 2 年前
        1
  •  3
  •   user17732522    2 年前

    如果源迭代器不是RandomAccessIterator,我能确定copy_n在源迭代程序上精确地执行n-1增量,如果是,则执行n增量吗?

    不,对增量的数量没有要求。

    如果迭代器只是一个输入迭代器,而不是前向迭代器 n n-1 递增到最后一个被取消引用的迭代器或之后未被取消引用但必须有效的迭代程序。输入迭代器不能以任何其他方式在源序列中进行迭代。

    如果迭代器是前向迭代器甚至是随机访问迭代器,则对增量的数量没有要求,并且实现也可以递减或进行比递增/递减更大的步骤。如果迭代器是连续的,它可以使用指针而不是迭代器来访问序列的元素。

    也不要求按顺序复制序列。

    唯一的复杂性要求是 n 分配。

    推荐文章