13

std::vector, std::list and std::deque have std::back_inserter, and std::set has std::inserter.

For std::stack and std::priority_queue I would assume the equivalent inserter would be a push() but I can't seem to find the correct function to call.

My intent is to be able to use the following function with the correct insert iterator:

#include <string>
#include <queue>
#include <iterator>

template<typename outiter>
void foo(outiter oitr)
{
   static const std::string s1 ("abcdefghji");
   static const std::string s2 ("1234567890");
   *oitr++ = s1;
   *oitr++ = s2;
}

int main()
{
   std::priority_queue<std::string> spq;
   std::stack<std::string> stk;

   foo(std::inserter(spq));
   foo(std::inserter(stk));

   return 0;
}
JFMR
  • 23,265
  • 4
  • 52
  • 76

2 Answers2

5

The other alternative (simpler) is just to use the underlying data structure (std::stack is usually implemented using std::deque) and accept that you have to use e.g. push_back() instead of push(). Saves having to code your own iterator, and doesn't particularly affect the clarity of the code. std::stack isn't your only choice for modelling the stack concept.

Zaz
  • 46,476
  • 14
  • 84
  • 101
Stuart Golodetz
  • 20,238
  • 4
  • 51
  • 80
4

You can always go your own way and implement an iterator yourself. I haven't verified this code but it should work. Emphasis on "I haven't verified."

template <class Container>
  class push_insert_iterator:
    public iterator<output_iterator_tag,void,void,void,void>
{
protected:
  Container* container;

public:
  typedef Container container_type;
  explicit push_insert_iterator(Container& x) : container(&x) {}
  push_insert_iterator<Container>& operator= (typename Container::const_reference value){
    container->push(value); return *this; }
  push_insert_iterator<Container>& operator* (){ return *this; }
  push_insert_iterator<Container>& operator++ (){ return *this; }
  push_insert_iterator<Container> operator++ (int){ return *this; }
};

I'd also add in the following function to help use it:

template<typename Container>
push_insert_iterator<Container> push_inserter(Container container){
    return push_insert_iterator<Container>(container);
}
wheaties
  • 35,646
  • 15
  • 94
  • 131
  • 2
    So what you're saying is that there isn't a standard one such as std::back_inserter or std::inserter - in short your answer is pretty good and what i'm currently doing... just hoped that i had missed something in the stl - don't like rolling out my own when there already is something in the stl –  Nov 06 '10 at 22:25
  • @sonicoder not that I know of. I only know front, back, and regular inserters besides the ones from ostream. You might look at Boost but I believe even these will leave you wanting for what you need. – wheaties Nov 06 '10 at 22:26
  • I think it should be: std::iterator –  Nov 06 '10 at 22:34
  • @sonicoder so you're right. iterator only has 5 arguments. I've also added in a helper function much akin to `back_inseter` or `front_inserter` functions. – wheaties Nov 06 '10 at 22:37
  • @sonicoder let me know how it works. I might want to use this myself in the future. – wheaties Nov 06 '10 at 22:43
  • I wonder why such an iterator class template was not added to the standard. Are there issues that we do not see? – lrineau Apr 17 '15 at 10:14