STL中有dereference_iterator吗?

发布于 2024-07-09 19:57:54 字数 515 浏览 5 评论 0原文

我想知道 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;
}

I was wondering if there is an iterator in the STL that dereferences the object pointed before returning it. This could be very useful when manipulating containers aggregating pointers. Here's an example of what I would like to be able to do:

#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;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

尘曦 2024-07-16 19:57:54

尝试 Boost 的 indirect_iterator

indirect_iterator 与它所包装的迭代器具有相同的类别。 例如,indirect_iterator 是随机访问迭代器。

Try Boost's indirect_iterator.

An indirect_iterator has the same category as the iterator it is wrapping. For example, an indirect_iterator<int**> is a random access iterator.

仅冇旳回忆 2024-07-16 19:57:54

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

您可以查看 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;
}

Assuming your actual use case is a bit more complex than a container of integer pointers!

You could check out the boost ptr containers
http://www.boost.org/doc/libs/1_35_0/libs/ptr_container/doc/reference.html

The containers contain dynamically allocated objects (ie pointers).
But all access to the objects (direct or via iterator) returns a reference to the object.

#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;
}
肤浅与狂妄 2024-07-16 19:57:54

如果无法使用 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);
}

If it is impossible using Boost, writing a custom iterator is not that hard. Here is an example of a "dereference iterator" that meets the InputIterator requirements :

#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);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文