2008-12-09 61 views
14

我想知道在STL中是否有一個迭代器在返回它之前解除引用的對象。這在操縱容器聚集指針時非常有用。下面是我想要做的一個例子:STL中是否有dereference_iterator?

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

回答

11

嘗試Boost的indirect_iterator

indirect_iterator與它正在包裝的迭代器具有相同的類別。例如,indirect_iterator<int**>是一個隨機訪問迭代器。

+0

正是我所要求的。對我沒有想到Boost的感到羞恥:-)!但是,我會期望這樣一個迭代器出現在標準庫中...... – 2008-12-09 10:54:59

4

如果使用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); 
} 
+0

您必須使用'using namespace std;'爲上面編譯。 – 2012-01-02 15:44:58

+0

@DavidDoria:更好的方法是在`input_iterator_tag`和`iterator_traits`前加上`std`前綴。 – 2012-01-03 08:16:26

4

假設你的實際用例比整數指針的容器複雜一點!

你可以檢查出的升壓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; 
} 
相關問題