que libreria iteradores iterador c++ c++11 stl iterator c++14

libreria - ¿Por qué no hay iteradores de emplazamiento en C++ 11 o C++ 14?



que es un iterador en java (2)

¿Hay alguna razón técnica por la que no pudiéramos tener front_emplacer, back_emplacer y emplacer?

No, no hay razón técnica. Como prueba, aquí hay una implementación completa de back_emplacer con una demostración de su caso de uso 1 ...

#include <iterator> #include <vector> #include <iostream> template<class Container> class back_emplace_iterator : public std::iterator< std::output_iterator_tag, void, void, void, void > { protected: Container* container; public: typedef Container container_type; explicit back_emplace_iterator(Container& x) : container(&x) {} template<class T> back_emplace_iterator<Container>& operator=(T&& t) { container->emplace_back(std::forward<T>(t)); return *this; } back_emplace_iterator& operator*() { return *this; } back_emplace_iterator& operator++() { return *this; } back_emplace_iterator& operator++(int) { return *this; } }; template< class Container > inline back_emplace_iterator<Container> back_emplacer( Container& c ) { return back_emplace_iterator<Container>(c); } struct Demo { int i; Demo(int i) : i(i) {} }; int main() { std::vector<int> x = {1,2,3,4,5}; std::vector<Demo> y; std::copy(x.begin(), x.end(), back_emplacer(y)); for (auto d : y) std::cout << d.i << std::endl; }

Posible problema conocido: ¿La referencia universal del operator= oculta un operator= copia / movimiento generado implícitamente operator= ? Si es así, estos deben definirse explícitamente de una manera que supere la referencia universal en la resolución de sobrecarga.

C ++ 98 tiene front_inserter , back_inserter y back_inserter , pero no parece haber ninguna versión de emplazamiento de estos en C ++ 11 o borrador C ++ 14. ¿Hay alguna razón técnica por la que no pudiéramos tener front_emplacer , back_emplacer y emplacer ?


Su caso de uso principal ya está cubierto por inserter , back_inserter y front_inserter . Ya hay un value_type && overload de operator= que se moverá al contenedor. Lo único que puede hacer emplacer sobre el inserter es llamar constructores explícitos.

Compare las sobrecargas comunes de container::insert , container::push_back y container::push_front to container::emplace , container::emplace_back and container::emplace_front

iterator insert( const_iterator pos, const value_type & value ); iterator insert( const_iterator pos, value_type && value ); template< class... Args > iterator emplace( const_iterator pos, Args&&... args ); void push_back( const value_type & value ); void push_back( value_type && value ); template< class... Args > void emplace_back( Args&&... args ); void push_front( const value_type & value ); void push_front( value_type && value ); template< class... Args > void emplace_front( Args&&... args );

Cada una de las variantes emplace toma un paquete de argumentos con los que construir el valor. operator = toma exactamente un argumento. Podrías escribir un emplacer que tomara una tupla de argumentos.

template<class Container> class back_emplace_iterator : public std::iterator< std::output_iterator_tag, void, void, void, void > { protected: Container* container; public: typedef Container container_type; explicit back_emplace_iterator(Container& x) : container(&x) {} template<typename ... Args> back_emplace_iterator<Container>& operator=(std::tuple<Args&&...> args) { std::apply(Container::emplace_back, std::tuple_cat(std::tie(*container), std::forward<std::tuple<Args&&...>>(args))); return *this; } back_emplace_iterator& operator*() { return *this; } back_emplace_iterator& operator++() { return *this; } back_emplace_iterator& operator++(int) { return *this; } };