In the context of this question, here is an implementation of a C++11 back_emplacer
that uses emplace_back
instead of how std::back_inserter
uses push_back
:
#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) {}
// ==== FROM UPDATE ====
template<class T>
using _not_self =
typename std::enable_if<
!std::is_same<
typename std::decay<T>::type,
back_emplace_iterator
>::value
>::type;
// =====================
// ==== UNIVERSAL REFERENCE ASSIGNMENT ====
template<class T, class = _not_self<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;
}
Does the universal reference operator=(T&&)
defeat generation of a default copy assignment operator and/or default move assignment operator?
If so, how can they be explicitly defined so that they will beat the universal reference version in overload resolution?
If not, do the implicitly generated ones beat the universal reference version?
Also, will the universal reference version work appropriately with initializer lists?
Update:
Added alias template _not_self
to restore default copy/move assignment. Thanks Alex.