print geeksforgeeks advance c++ stl iterator

geeksforgeeks - list iterator c++



¿Hay un dereference_iterator en el STL? (3)

Me preguntaba si hay un iterador en el STL que desreferencia el objeto apuntado antes de devolverlo. Esto podría ser muy útil al manipular contenedores que agregan punteros. Aquí hay un ejemplo de lo que me gustaría poder hacer:

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


¡Suponiendo que su caso de uso real es un poco más complejo que un contenedor de punteros enteros!

Podrías echarle un vistazo a los contenedores ptr boost
http://www.boost.org/doc/libs/1_35_0/libs/ptr_container/doc/reference.html

Los contenedores contienen objetos dinámicamente asignados (es decir, punteros).
Pero todo acceso a los objetos (directo o vía iterador) devuelve una referencia al objeto.

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


Prueba el valor indirect_iterator de Boost.

Un indirect_iterator tiene la misma categoría que el iterador que está envolviendo. Por ejemplo, un indirect_iterator<int**> es un iterador de acceso aleatorio.


Si no es posible usar Boost, escribir un iterador personalizado no es tan difícil. Aquí hay un ejemplo de un "iterador de desreferencia" que cumple con los requisitos de 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); }