2012-05-29 12 views
6

Cómo borrar tipo de iteradores de salida como std::insert_iterator y std::back_insert_iterator? ¿Es posible usar boost any_iterator para hacerlo?iterador de salida de C++ borrado por tipo

#include <boost/range.hpp> 
#include <boost/range/detail/any_iterator.hpp> 
#include <vector> 

typedef boost::range_detail::any_iterator< 
    int, boost::incrementable_traversal_tag, int &, std::ptrdiff_t > It; 

int main() 
{ 
    std::vector<int> v; 
    It outIt(v.begin()); // compiles 
    It inserter(std::back_inserter(v)); // does not compile 
    return 0; 
} 
+0

¿Qué quiere decir con "erase type"? –

+0

@EitanT: debe buscar "borrado de tipo C++", pero para una definición breve "el proceso de convertir una amplia variedad de tipos con una interfaz común en un tipo con esa misma interfaz". Boost :: Cualquiera sería el ejemplo canónico. –

+0

@JesseGood Aaa Sé lo que es eso, nunca supe que se llama "borrado de tipo". Doh! –

Respuesta

6

any_iterator no está diseñado para su uso con iteradores de salida, que es lo que back_insert_iterator es (o, para el caso, iteradores de entrada).

back_insert_iterator se define a heredar de iterator<output_iterator_tag, void, void, void, void> es decir, su value_type, reference_type, distance_type y pointer_type son todos void, pero any_iterator espera para poder indirecta a través de su iterador respaldo a un valor no nulo. Tal vez sería mejor llamar any_value_iterator; pero luego es una plantilla de clase detail.

+0

Gracias. ¿Hay alguna alternativa en Boost? –

+0

No es que yo sepa; el problema es que 'boost :: iterator_facade' espera ser capaz de definir' operator [] 'y' operator-> 'in-class. No debería ser demasiado difícil definirse usando 'boost :: function' para envolver' operator = '(que es la única parte de un iterador de salida que realmente importa). – ecatmur

3

Así que implementé mi propio uso de Boost.

#include <boost/function_output_iterator.hpp> 
#include <boost/function.hpp> 

template < class T > 
class AnyInserter : public boost::function_output_iterator< boost::function< void (const T & value) > > 
{ 
private: 
    typedef typename boost::function_output_iterator< boost::function< void (const T & value) > > BaseType; 
    template < class OutIt > struct Insert 
    { 
     Insert(OutIt it) : m_it(it) {} 
     void operator() (const T & value) { m_it++ = value; } 
     OutIt m_it; 
    }; 
public: 
    template < class OutIt > 
     explicit AnyInserter(const OutIt & it) : BaseType(Insert<OutIt>(it)) {} 
}; 

template < class OutIt > 
    inline AnyInserter< typename OutIt::container_type::value_type > 
    makeAnyInserter(const OutIt & it) 
    { 
     return AnyInserter< typename OutIt::container_type::value_type >(it); 
    } 
+2

Eso se ve bien. Un punto es que en lugar de 'typename OutIt :: container_type :: value_type' puede usar' typename std :: iterator_traits :: value_type' para que pueda usar su plantilla con p. Ej. punteros crudos. – ecatmur

Cuestiones relacionadas