【问题标题】:Iterator which only ever yields a single value?只产生一个值的迭代器?
【发布时间】:2016-10-15 14:20:51
【问题描述】:

一些 STL 算法(以及在其他情况下可以想到的类似 STL 的算法)通过迭代器获取输入。有时我发现自己想要传递一个 (const) 迭代器作为他们的输入之一,它只是不断产生相同的值(或 const 引用内存中的相同值)。例如,您可以使用它来实现 std::fill 使用 std::copy_nstd::distance(假设您有目标的结尾)。

那么,标准库或其中一个 TS 是否在任何地方(C++17 或更早版本)都有这个?

注意:我不是在谈论一个 const 迭代器,而是一个从不前进并不断产生相同东西的迭代器。

【问题讨论】:

  • 您指的是哪种“STL 算法”?事实上,我所知道的几乎所有东西都会提前或以其他方式计算与迭代器相关的东西。声明一个接受迭代器值的库函数是没有意义的,只是为了取消引用它,否则什么也不做。我认为你误会了什么。
  • @SamVarshavchik:见编辑。
  • 您的编辑无法解释您正在查看哪些特定的“STL 算法”。
  • 如果您尝试将不可递增/可递减的迭代器传递给需要推进所述迭代器的函数,那么它将无法正常工作。
  • @ArchbishopOfBanterbury:其实我之前举了一个无效的例子。让我们再试试。

标签: c++ c++17


【解决方案1】:

只需创建一个实现forward iterator interface 的类,其解引用运算符返回您的单个值。

【讨论】:

    【解决方案2】:

    这个例子实现了最简单的迭代器接口,std::iterator。

    签名中的 ssize_t 参数是用于差异的类型,因为即使在 STL 中也没有固定 :)

    它返回多少值由运算符 == 的行为以及 end() 方法返回的值决定。

    template <typename E>
    class IteratorExample
    {
        ...
    
        struct StlIterator
        {
            ...
    
            const E & operator * ()
            {
                ...
            }
    
            const E * operator -> ()
            {
                return &(operator * ());
            }
    
            StlIterator & operator ++ ()
            {
                ...
            }
    
            StlIterator & operator ++ (int)
            {
                ...
            }
    
            bool operator == (const StlIterator &other)
            {
                ...
            }
    
            bool operator != (const StlIterator &other)
            {
                return (operator == (other)) == false;
            }
    
            typedef E value_type;
            typedef size_t difference_type;
            typedef E * pointer;
            typedef E & reference;
            typedef std::input_iterator_tag iterator_category;
        };
    
        StlIterator begin() const
        {
            return StlIterator(...);
        }
    
        StlIterator end() const
        {
            return StlIterator(...);
        }
    };
    

    【讨论】:

    • 在 C++17 中不会弃用 std::iterator 吗?
    • 是的,但我们还不知道是否会有一种新的便利机制取代迭代器特征,或者我们实际上必须为每个迭代器编写大量样板......跨度>
    • 刚刚为您现代化了 :)
    • 老实说,我只是在我真正的实际代码中为自己现代化了它,所以一旦 c++ 17 成为新标准,我就不会收到警告?
    • 我其实不明白采用ref&lt;Iterator&gt;的方法。是std::ref 吗? Iterator 类型从何而来? iter 字段在哪里?字段和参数怎么可能同名?
    【解决方案3】:

    对于copy_n,第一个参数应满足InputIterator 的要求。然而,下面的示例是一个最小的工作实现,缺少InputIterator 的一些要求:

    #include <iostream>
    #include <vector>
    #include <algorithm>
    #include <iterator>
    template <typename T, T t>
    struct It:public std::iterator<std::input_iterator_tag, T>
    {
        constexpr auto& operator++() const{
            return *this;
        }
        constexpr auto& operator+(size_t) const{
            return *this;
        }
        constexpr auto operator*() const{
            return t;
        }
    };
    
    
    int main(){
     //an iterator with constant value of 1
        It<int,1> in;
        std::vector<int> out;
        std::copy_n(in, 4, std::back_inserter(out));
    }
    

    【讨论】:

      猜你喜欢
      • 2016-01-30
      • 2017-03-22
      • 2016-06-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-12
      • 2011-04-06
      • 2012-10-23
      相关资源
      最近更新 更多