C++98 has front_inserter
, back_inserter
, and inserter
, but there don't seem to be any emplacement versions of these in C++11 or draft C++14. Is there any technical reason we couldn't have front_emplacer
, back_emplacer
, and emplacer
?

- 362,284
- 104
- 897
- 1,065

- 12,972
- 8
- 50
- 91
-
5What are you going to assign into them? Tuples of arguments? – Pavel Anossov Sep 10 '13 at 17:13
-
@PavelAnossov: It would allow conversions constructors at least `*front_inserter(string_vector) = "hello world";` – Mooing Duck Sep 10 '13 at 17:17
-
1@MooingDuck: that already works with inserters – Pavel Anossov Sep 10 '13 at 17:21
-
3@PavelAnossov: But because the inserters insist on inserting an object of the type held by the container, you pay a penalty (typically a move) for inserting a different type. Emplacement would avoid that penalty. – KnowItAllWannabe Sep 10 '13 at 17:22
-
Can you give a sensible use case? – Walter Sep 10 '13 at 17:30
-
4@Walter: Use Case 1: I have a container of ints and a container of objects, where each object can be initialized with an int. I want to append to the container of objects a sequence of new objects initialized with the ints, and I want to do it maximally efficiently. Use case 2: I have a library of algorithms in the STL style, but they operate on multiple input sequences at once (like the two-sequence version of std::transform). I want to add new objects to the front of a sequence, where the new objects' n constructor arguments are taken from the n input sequences I'm processing. – KnowItAllWannabe Sep 10 '13 at 17:39
-
2@Walter: inserting into an array of objects where the objects are large and/or legacy types that are copiable but not movable . It's not exactly a stretch. – Mooing Duck Sep 10 '13 at 17:48
-
@KnowItAllWannabe The problem is that `back_emplacer`, when used with algorithms, would accept only a single constructor argument (such as your `int`). Algorithms such as `std::generate` do no provide possibility to pass multiple arguments to be forwarded to `back_emplacer`. – Daniel Langr Sep 06 '19 at 07:12
2 Answers
Is there any technical reason we couldn't have front_emplacer, back_emplacer, and emplacer?
No, there is no technical reason. As proof, here is a complete implementation of back_emplacer
with a demo of your Use Case 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;
}
Possible Known Issue: Does the universal reference of operator=
hide an implicitly generated copy/move operator=
? If so these need to be explicitly defined in a way that beats the universal reference in overload resolution.

- 71,951
- 46
- 188
- 305

- 66,139
- 40
- 186
- 319
-
I have [asked another question](http://stackoverflow.com/questions/18728257/back-emplacer-implementation-default-operator) regarding the known issue. – Andrew Tomazos Sep 10 '13 at 20:33
-
@MooingDuck: Proxy class for what? Go have a look at the libstdc++ implementation of `back_inserter`. It is in `bits/stl_iterator.h`. – Andrew Tomazos Sep 10 '13 at 20:50
-
@MooingDuck: So it is required by the C++ standard to not use a proxy class, but to implement it the way shown. See N3485 24.5.2.2.3. – Andrew Tomazos Sep 10 '13 at 21:25
-
Existence proofs are awesome :-) I'm marking this as the answer. Thanks for the great work! – KnowItAllWannabe Sep 10 '13 at 22:17
-
@user1131467: Wow, so it is. That's strange to me, I wonder why they decided to do it that way? – Mooing Duck Sep 10 '13 at 22:48
-
1Is the advantage of this over plain `back_inserter_iterator`? https://stackoverflow.com/questions/54303852/is-there-a-back-inserter-variant-that-takes-advantage-of-move/54304086#54304086 – alfC Jan 22 '19 at 08:46
-
1@alfC: Yeah I now think the notion of `back_emplace_iterator` is conceptually flawed. "emplace"-style operations take a pack of arguments and then forward them to the constructor. See for example `std::vector::emplace_back`. Such an operation does not fit into the iterator paradigm, because the underlying iterator abstraction does not support it. – Andrew Tomazos Jul 13 '21 at 22:04
Your main use case is already covered by inserter
, back_inserter
and front_inserter
. There is already a value_type &&
overload of operator=
that will move into the container. The only thing emplacer
could do over inserter
is call explicit constructors.
Compare the common overloads of container::insert
, container::push_back
and 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 );
Each of the emplace
variants takes a pack of arguments with which to construct the value. operator =
takes exactly one argument. You could write an emplacer
that took a tuple of arguments.
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; }
};

- 52,200
- 2
- 44
- 75