Ответ 1
Попробуйте Boost indirect_iterator
.
An indirect_iterator
имеет ту же категорию, что итератор, он обертывает. Например, indirect_iterator<int**>
является итератором с произвольным доступом.
Мне было интересно, есть ли в 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;
}
Попробуйте Boost indirect_iterator
.
An indirect_iterator
имеет ту же категорию, что итератор, он обертывает. Например, indirect_iterator<int**>
является итератором с произвольным доступом.
Если невозможно использовать 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);
}
Предполагая, что ваш фактический пример использования немного сложнее, чем контейнер целых указателей!
Вы можете проверить контейнеры 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;
}