【问题标题】:Is there a dereference_iterator in the STL?STL 中有 dereference_iterator 吗?
【发布时间】:2010-09-26 00:19:43
【问题描述】:

我想知道 STL 中是否有一个迭代器在返回之前取消引用指向的对象。这在操作容器聚合指针时可能非常有用。这是我想要做的一个例子:

#include <vector>
#include <iterator>
#include <algorithm>

using namespace std;

int main()
{
  vector<int*> vec;

  int i = 1;
  int j = 2;
  int k = 3;

  vec.push_back(&i);
  vec.push_back(&j);
  vec.push_back(&k);

  copy(deref_iterator(vec.begin()), 
       deref_iterator(vec.end()), 
       ostream_iterator<int>(cout, " ")); // prints "1 2 3"

  return 0;
}

【问题讨论】:

    标签: c++ stl iterator


    【解决方案1】:

    试试 Boost 的indirect_iterator

    indirect_iterator 与它所包装的迭代器具有相同的类别。例如,indirect_iterator&lt;int**&gt; 是一个随机访问迭代器。

    【讨论】:

    • 正是我所要求的。我为没有考虑 Boost 感到羞耻 :-)!但是,我本来希望标准库中会出现这样的迭代器...
    • 嗯,更难的问题能解决吗?我想对 ptrs 的向量进行排序或对其应用 中的函数进行分区。这里的问题是我需要在容器中交换指针,同时取消对对象值的引用。
    【解决方案2】:

    假设您的实际用例比整数指针容器复杂一点!

    您可以查看 boost ptr 容器
    http://www.boost.org/doc/libs/1_35_0/libs/ptr_container/doc/reference.html

    容器包含动态分配的对象(即指针)。
    但是对对象的所有访问(直接或通过迭代器)都会返回对该对象的引用。

    #include <boost/ptr_container/ptr_vector.hpp>
    #include <iostream>
    #include <iterator>
    #include <algorithm>
    
    using namespace std;
    
    int main()
    {
      boost::ptr_vector<int> vec;
    
      vec.push_back(new int(1));
      vec.push_back(new int(2));
      vec.push_back(new int(3));
    
      copy(vec.begin(),vec.end(),
           ostream_iterator<int>(std::cout, " ")); // prints "1 2 3 "
    
      return 0;
    }
    

    【讨论】:

    • 好吧,如果您希望容器拥有元素的所有权,这很好。在处理指向具有实体语义的对象的指针时,indirect_iterator 似乎更合适,这些对象已经由其他东西拥有(或在堆栈上分配)。
    【解决方案3】:

    如果无法使用 Boost,编写自定义迭代器并不难。下面是一个满足 InputIterator 要求的“解引用迭代器”示例:

    #include <iterator>
    
    template <typename T>
    struct PointedType;
    
    template <typename T>
    struct PointedType<T*>
    {
      typedef T value_type;
    };
    
    template <typename InputIterator>
    struct DerefIterator
    {
      typedef input_iterator_tag iterator_category;
      typedef typename PointedType<
                typename iterator_traits<InputIterator>::value_type>::value_type
                value_type;
      typedef typename iterator_traits<InputIterator>::difference_type
                difference_type;
      typedef value_type* pointer;
      typedef value_type& reference;
    
      public:
        explicit DerefIterator(const InputIterator& ii)
          : it(ii) {}
    
        // Returns the object pointed by the object referenced by it
        reference operator*()  const { return **it; }
        pointer   operator->() const { return *it; }
    
        DerefIterator& operator++()
        {
            ++it;
            return *this;
        }
    
        DerefIterator operator++(int)
        {
            DerefIterator tmp = *this;
            ++it;
            return tmp;
        }
    
        bool equals(const DerefIterator<InputIterator> & di) const
        {
            return di.it == it;
        }
    
      private:
        InputIterator it;
    };
    
    // Equality functions
    
    template <typename InputIterator>
    inline bool operator==(const DerefIterator<InputIterator>& di1, 
                           const DerefIterator<InputIterator>& di2)
    {
      return di1.equals(di2);
    }
    
    template <typename InputIterator>
    inline bool operator!=(const DerefIterator<InputIterator>& di1, 
                           const DerefIterator<InputIterator>& di2)
    {
      return ! (di1 == di2);
    }
    
    //Helper function
    
    template <typename InputIterator>
    DerefIterator<InputIterator> deref_iterator(const InputIterator& ii)
    {
      return DerefIterator<InputIterator>(ii);
    }
    

    【讨论】:

    • 你必须使用'using namespace std;'用于编译上述内容。
    • @DavidDoria:更好的方法是在input_iterator_tagiterator_traits 前加上std 前缀。
    猜你喜欢
    • 2023-03-25
    • 2014-09-05
    • 1970-01-01
    • 2022-11-13
    • 2020-10-23
    • 1970-01-01
    • 1970-01-01
    • 2018-02-22
    • 1970-01-01
    相关资源
    最近更新 更多