Insert into an STL queue using std::copyC++ back_insert_iterator for Container-AdaptersWhy doesn't my custom iterator work with the STL copy?How can I copy an entire vector into a queue?Idiomatically reverse a stack?How do I copy a file in Python?What is the difference between a deep copy and a shallow copy?Why is “using namespace std” considered bad practice?How to clone or copy a list?What is the copy-and-swap idiom?Pretty-print C++ STL containersWhy can't I perform a std::copy on a vector of std::shared_ptr's in C++0x?Why is reading lines from stdin much slower in C++ than Python?Image Processing: Algorithm Improvement for 'Coca-Cola Can' RecognitionWhat is the difference between the `COPY` and `ADD` commands in a Dockerfile?
What reasons are there for a Capitalist to oppose a 100% inheritance tax?
Assassin's bullet with mercury
How do I deal with an unproductive colleague in a small company?
Do UK voters know if their MP will be the Speaker of the House?
GFCI outlets - can they be repaired? Are they really needed at the end of a circuit?
What does “the session was packed” mean in this context?
How badly should I try to prevent a user from XSSing themselves?
Are there any examples of a variable being normally distributed that is *not* due to the Central Limit Theorem?
Avoiding the "not like other girls" trope?
What is a romance in Latin?
What type of content (depth/breadth) is expected for a short presentation for Asst Professor interview in the UK?
Is there a hemisphere-neutral way of specifying a season?
Alternative to sending password over mail?
Can the Meissner effect explain very large floating structures?
Is it logically or scientifically possible to artificially send energy to the body?
Plagiarism or not?
Forgetting the musical notes while performing in concert
How dangerous is XSS?
What method can I use to design a dungeon difficult enough that the PCs can't make it through without killing them?
What are some good books on Machine Learning and AI like Krugman, Wells and Graddy's "Essentials of Economics"
Can my sorcerer use a spellbook only to collect spells and scribe scrolls, not cast?
One verb to replace 'be a member of' a club
Which is the best way to check return result?
How much of data wrangling is a data scientist's job?
Insert into an STL queue using std::copy
C++ back_insert_iterator for Container-AdaptersWhy doesn't my custom iterator work with the STL copy?How can I copy an entire vector into a queue?Idiomatically reverse a stack?How do I copy a file in Python?What is the difference between a deep copy and a shallow copy?Why is “using namespace std” considered bad practice?How to clone or copy a list?What is the copy-and-swap idiom?Pretty-print C++ STL containersWhy can't I perform a std::copy on a vector of std::shared_ptr's in C++0x?Why is reading lines from stdin much slower in C++ than Python?Image Processing: Algorithm Improvement for 'Coca-Cola Can' RecognitionWhat is the difference between the `COPY` and `ADD` commands in a Dockerfile?
I'd like to use std::copy to insert elements into a queue like this:
vector<int> v;
v.push_back( 1 );
v.push_back( 2 );
queue<int> q;
copy( v.begin(), v.end(), insert_iterator< queue<int> >( q, q.front() ) );
But this fails to compile, complaining that begin is not a member of std::queue.
Note: I tried it with std::inserter too - this also failed, this time saying that 'reference' is not a member of 'std::queue'. std::back_inserter and std::back_insert_iterator also fail with the same error.
Am I missing something obvious, or do insert_iterators just not work with queues?
c++ stl copy queue insert-iterator
add a comment |
I'd like to use std::copy to insert elements into a queue like this:
vector<int> v;
v.push_back( 1 );
v.push_back( 2 );
queue<int> q;
copy( v.begin(), v.end(), insert_iterator< queue<int> >( q, q.front() ) );
But this fails to compile, complaining that begin is not a member of std::queue.
Note: I tried it with std::inserter too - this also failed, this time saying that 'reference' is not a member of 'std::queue'. std::back_inserter and std::back_insert_iterator also fail with the same error.
Am I missing something obvious, or do insert_iterators just not work with queues?
c++ stl copy queue insert-iterator
Although the answers you've been given are good, personally I would just avoid std::queue and any other crippled container adapter.
– Kylotan
Nov 12 '09 at 17:04
Yes, sbi and Naveen's suggestion to use a deque would be a good alternative.
– Andy Balaam
Nov 13 '09 at 9:23
add a comment |
I'd like to use std::copy to insert elements into a queue like this:
vector<int> v;
v.push_back( 1 );
v.push_back( 2 );
queue<int> q;
copy( v.begin(), v.end(), insert_iterator< queue<int> >( q, q.front() ) );
But this fails to compile, complaining that begin is not a member of std::queue.
Note: I tried it with std::inserter too - this also failed, this time saying that 'reference' is not a member of 'std::queue'. std::back_inserter and std::back_insert_iterator also fail with the same error.
Am I missing something obvious, or do insert_iterators just not work with queues?
c++ stl copy queue insert-iterator
I'd like to use std::copy to insert elements into a queue like this:
vector<int> v;
v.push_back( 1 );
v.push_back( 2 );
queue<int> q;
copy( v.begin(), v.end(), insert_iterator< queue<int> >( q, q.front() ) );
But this fails to compile, complaining that begin is not a member of std::queue.
Note: I tried it with std::inserter too - this also failed, this time saying that 'reference' is not a member of 'std::queue'. std::back_inserter and std::back_insert_iterator also fail with the same error.
Am I missing something obvious, or do insert_iterators just not work with queues?
c++ stl copy queue insert-iterator
c++ stl copy queue insert-iterator
edited May 4 '18 at 20:08
El Profesor
10.9k32341
10.9k32341
asked Nov 12 '09 at 16:28
Andy BalaamAndy Balaam
3,38742731
3,38742731
Although the answers you've been given are good, personally I would just avoid std::queue and any other crippled container adapter.
– Kylotan
Nov 12 '09 at 17:04
Yes, sbi and Naveen's suggestion to use a deque would be a good alternative.
– Andy Balaam
Nov 13 '09 at 9:23
add a comment |
Although the answers you've been given are good, personally I would just avoid std::queue and any other crippled container adapter.
– Kylotan
Nov 12 '09 at 17:04
Yes, sbi and Naveen's suggestion to use a deque would be a good alternative.
– Andy Balaam
Nov 13 '09 at 9:23
Although the answers you've been given are good, personally I would just avoid std::queue and any other crippled container adapter.
– Kylotan
Nov 12 '09 at 17:04
Although the answers you've been given are good, personally I would just avoid std::queue and any other crippled container adapter.
– Kylotan
Nov 12 '09 at 17:04
Yes, sbi and Naveen's suggestion to use a deque would be a good alternative.
– Andy Balaam
Nov 13 '09 at 9:23
Yes, sbi and Naveen's suggestion to use a deque would be a good alternative.
– Andy Balaam
Nov 13 '09 at 9:23
add a comment |
8 Answers
8
active
oldest
votes
Unfortunately std::queue 'adapts' the function known as push_back to just push which means that the standard back_insert_iterator doesn't work.
Probably the simplest way (albeit conceptually ugly) is to adapt the container adapter with a short lived container adapter adapter[sic] (eugh!) that lives as long as the back insert iterator.
template<class T>
class QueueAdapter
public:
QueueAdapter(std::queue<T>& q) : _q(q)
void push_back(const T& t) _q.push(t);
private:
std::queue<T>& _q;
;
Used like this:
std::queue<int> qi;
QueueAdapter< std::queue<int> > qiqa( qi );
std::copy( v.begin(), v.end(), std::back_inserter( qiqa ) );
3
Genius. Neat, beautiful, and exposes the odd decision to use the name push instead of push_back in the first place.
– Andy Balaam
Nov 12 '09 at 17:00
2
It's notpush_back, because the point where the insertions happen don't matter conceptually. Besides, what wouldpush_backmean for apriority_queue?
– UncleBens
Nov 12 '09 at 17:24
1
Conceptually it makes sense, I just used the work 'unfortunately' because it means that it closes off using theback_insert_iteratorwhich could be really useful.
– CB Bailey
Nov 12 '09 at 17:32
I agree with Kylotan's comment to the question. If you want to do things beyond what the queue ADT allows (basically pushing and popping), there's little point fighting the queue adaptor. - +1 to your elegant answer, though.
– UncleBens
Nov 12 '09 at 20:34
add a comment |
Queue does not allow iteration through its elements.
From the SGI STL Docs:
A queue is an adaptor that provides a
restricted subset of Container
functionality A queue is a "first in
first out" (FIFO) data structure. 1
That is, elements are added to the
back of the queue and may be removed
from the front; Q.front() is the
element that was added to the queue
least recently. Queue does not allow
iteration through its elements. [2]
You can make this work, but you can't use insert_iterator. You'll have to write something like queue_inserter that presents an iterator interface.
Update I couldn't help myself and deicded to try to implement the iterator you need. Here are the results:
template< typename T, typename U >
class queue_inserter
queue<T, U> &qu;
public:
queue_inserter(queue<T,U> &q) : qu(q)
queue_inserter<T,U> operator ++ (int) return *this;
queue_inserter<T,U> operator * () return *this;
void operator = (const T &val) qu.push(val);
;
template< typename T, typename U >
queue_inserter<T,U> make_queue_inserter(queue<T,U> &q)
return queue_inserter<T,U>(q);
This works great for functions like this:
template<typename II, typename OI>
void mycopy(II b, II e, OI oi)
while (b != e) *oi++ = *b++;
But it doesn't work with the STL copy because the STL is stupid.
1
Andy isn't trying to iteratoe through the queue, but to append to it.
– sbi
Nov 12 '09 at 16:42
1
Otherwise your answer is reasonable, though.:)+1
– sbi
Nov 12 '09 at 16:44
2
Why not implement the queue_inserter to correspond to the back_insert_iterator interface?std::copyisn't 'stupid' (IMHO!), it just requires an output iterator which isn't an onerous interface.
– CB Bailey
Nov 12 '09 at 17:48
4
Your queue_inserter isn't assignable, but apart from that you don't have to derive fromiterator, you only have to provide a specialization foriterator_traitsif you want to able to use your iterator with standard algorithms.
– CB Bailey
Nov 12 '09 at 20:28
2
BTW,std::copyin particular commonly needs to know more about the iterators, so it can pick an optimal way to do it: e.g pointers + PODs can be memmoved.
– UncleBens
Nov 12 '09 at 23:05
|
show 4 more comments
std::queue isn't a container in the STL sense, it's a container adapter with very limited functionality. For what you seem to need either std::vector or std::deque ("double-ended queue, which is a "real container"), seems the right choice.
Or use a for loop to push into the queue. What I'm doing doesn't seem unreasonable, though, does it?
– Andy Balaam
Nov 12 '09 at 16:37
Not it isn't. See Frank's answer as to how to achieve what you want.
– sbi
Nov 12 '09 at 16:43
No it does not (functionally), but you will have to roll your own inserter unfortunately.
– Matthieu M.
Nov 12 '09 at 16:44
add a comment |
I'm pretty sure it just won't work -- a queue provides push, but an insert iterator expects to use push_front or push_back. There's no real reason you couldn't write your own push_insert_iterator (or whatever name you prefer) but it is a bit of a pain...
add a comment |
insert_iterator and back_insert_iterator only work on containers (or adaptors) with (respectively) insert and push_back methods - queue doesn't have these. You could write your own iterator modelled on these, something like this:
template <typename Container>
class push_iterator : public iterator<output_iterator_tag,void,void,void,void>
public:
explicit push_iterator(Container &c) : container(c)
push_iterator &operator*() return *this;
push_iterator &operator++() return *this;
push_iterator &operator++(int) return *this;
push_iterator &operator=(typename Container::const_reference value)
container.push(value);
return *this;
private:
Container &container;
;
Unless such a thing already exists, but I'm pretty sure it doesn't.
I was just about to accept this answer, which looks excellent (although I haven't tried it) but Charles pipped you at the post.
– Andy Balaam
Nov 12 '09 at 17:01
It would be nice to have such an iterator in the Standard Library. However, regarding your implementation, I think it would be safer to have the dereferencing operator return a proxy object instead of the current object. Indeed, the code as it is allows you to dopush_iterator< queue< int > > it; it = 42;, which is wrong (it also allows you to do******it, which is not more correct). Theoperator*should return an object defining theoperator=.
– Luc Touraille
Nov 17 '11 at 14:30
You could also add to your answer the usual helper function allowing one to omit the container type:template < typename Container > push_iterator< Container > pusher( Container & c ) return push_iterator< Container >( c );.
– Luc Touraille
Nov 17 '11 at 14:32
add a comment |
What you need is a push_inserter (i.e. an inserter that performs pushes into the queue). As far as I know, there is no such iterator in the STL. What I usually do is sadly fall back to the good old for loop.
If you have the courage, you can roll your own iterator, something along these lines:
template <typename Container>
class push_insert_iterator
public:
typedef Container container_type;
typedef typename Container::value_type value_type;
explicit push_insert_iterator(container_type & c)
: container(c)
// construct with container
push_insert_iterator<container_type> & operator=(const value_type & v)
//push value into the queue
container.push(v);
return (*this);
push_insert_iterator<container_type> & operator*()
return (*this);
push_insert_iterator<container_type> & operator++()
// Do nothing
return (*this);
push_insert_iterator<container_type> operator++(int)
// Do nothing
return (*this);
protected:
container_type & container; // reference to container
;
template <typename Container>
inline push_insert_iterator<Container> push_inserter(Container & c)
return push_insert_iterator<Container>(c);
This is just a draft but you got the idea. Works with any container (or, well, container adapters) with a push method (e.g. queue, stack).
It's called "back inserter" in the STL and you get one fromback_inserter. However, this doesn't work onstd::queue.
– sbi
Nov 12 '09 at 16:41
1
I know what a back_insert_iterator is: an iterator that performs push_back into a container. Queue does not have a push_back method, that is why back_insert_iterator doesn't work. The method for adding elements in a queue is push, hence the push_insert_iterator idea...
– Luc Touraille
Nov 12 '09 at 16:44
@sbi: Considering that "inserting" an element into a queue is made via the queue::push() function,push_inserteris not a bad name, IMHO
– Éric Malenfant
Nov 12 '09 at 16:50
@Éric: No, it isn't. Not at all. However, my comment was written before Luc's answer ever had apush_inserter.:)
– sbi
Nov 12 '09 at 23:36
add a comment |
std::queue is not one of the basic containers in STL. It is a container adaptor which is built using one of the basic STL containers ( in this case one of the sequential container either std::vector std::deque or std::list). It is designed specifically for FIFO behaviour and does not provide random insertion at the given iterator which you want for the insert_iterator to work. Hence it will not be possible to use queue like this.
The easiest way I could think of to do this is to:
class PushFunctor
public:
PushFunctor(std::queue<int>& q) : myQ(q)
void operator()(int n)
myQ.push(n);
private:
std::queue<int>& myQ;
;
And use it like:
queue<int> q;
PushFunctor p(q);
std::for_each(v.begin(), v.end(), p);
This is also a great idea.
– Andy Balaam
Nov 12 '09 at 17:02
add a comment |
In this simple case, you can write:
vector<int> v;
v.push_back( 1 );
v.push_back( 2 );
queue<int, vector<int> > q(v);
This will make a copy of the vector and use it as the underlying container of the queue.
Of course, this approach won't work if you need to enqueue things after the queue has been constructed.
Very good point. Unfortunately my example was too simplified and that isn't what I want to do.
– Andy Balaam
Nov 12 '09 at 16:54
2
queue cannot use a vector. The container must supportpop_front.
– UncleBens
Nov 12 '09 at 17:06
Argh! You're right. Due to templates, my test didn't show this. Well, I guess you can still create a queue that allows you to inspectfront()andback()... :P
– Thomas
Nov 12 '09 at 20:24
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f1723515%2finsert-into-an-stl-queue-using-stdcopy%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
8 Answers
8
active
oldest
votes
8 Answers
8
active
oldest
votes
active
oldest
votes
active
oldest
votes
Unfortunately std::queue 'adapts' the function known as push_back to just push which means that the standard back_insert_iterator doesn't work.
Probably the simplest way (albeit conceptually ugly) is to adapt the container adapter with a short lived container adapter adapter[sic] (eugh!) that lives as long as the back insert iterator.
template<class T>
class QueueAdapter
public:
QueueAdapter(std::queue<T>& q) : _q(q)
void push_back(const T& t) _q.push(t);
private:
std::queue<T>& _q;
;
Used like this:
std::queue<int> qi;
QueueAdapter< std::queue<int> > qiqa( qi );
std::copy( v.begin(), v.end(), std::back_inserter( qiqa ) );
3
Genius. Neat, beautiful, and exposes the odd decision to use the name push instead of push_back in the first place.
– Andy Balaam
Nov 12 '09 at 17:00
2
It's notpush_back, because the point where the insertions happen don't matter conceptually. Besides, what wouldpush_backmean for apriority_queue?
– UncleBens
Nov 12 '09 at 17:24
1
Conceptually it makes sense, I just used the work 'unfortunately' because it means that it closes off using theback_insert_iteratorwhich could be really useful.
– CB Bailey
Nov 12 '09 at 17:32
I agree with Kylotan's comment to the question. If you want to do things beyond what the queue ADT allows (basically pushing and popping), there's little point fighting the queue adaptor. - +1 to your elegant answer, though.
– UncleBens
Nov 12 '09 at 20:34
add a comment |
Unfortunately std::queue 'adapts' the function known as push_back to just push which means that the standard back_insert_iterator doesn't work.
Probably the simplest way (albeit conceptually ugly) is to adapt the container adapter with a short lived container adapter adapter[sic] (eugh!) that lives as long as the back insert iterator.
template<class T>
class QueueAdapter
public:
QueueAdapter(std::queue<T>& q) : _q(q)
void push_back(const T& t) _q.push(t);
private:
std::queue<T>& _q;
;
Used like this:
std::queue<int> qi;
QueueAdapter< std::queue<int> > qiqa( qi );
std::copy( v.begin(), v.end(), std::back_inserter( qiqa ) );
3
Genius. Neat, beautiful, and exposes the odd decision to use the name push instead of push_back in the first place.
– Andy Balaam
Nov 12 '09 at 17:00
2
It's notpush_back, because the point where the insertions happen don't matter conceptually. Besides, what wouldpush_backmean for apriority_queue?
– UncleBens
Nov 12 '09 at 17:24
1
Conceptually it makes sense, I just used the work 'unfortunately' because it means that it closes off using theback_insert_iteratorwhich could be really useful.
– CB Bailey
Nov 12 '09 at 17:32
I agree with Kylotan's comment to the question. If you want to do things beyond what the queue ADT allows (basically pushing and popping), there's little point fighting the queue adaptor. - +1 to your elegant answer, though.
– UncleBens
Nov 12 '09 at 20:34
add a comment |
Unfortunately std::queue 'adapts' the function known as push_back to just push which means that the standard back_insert_iterator doesn't work.
Probably the simplest way (albeit conceptually ugly) is to adapt the container adapter with a short lived container adapter adapter[sic] (eugh!) that lives as long as the back insert iterator.
template<class T>
class QueueAdapter
public:
QueueAdapter(std::queue<T>& q) : _q(q)
void push_back(const T& t) _q.push(t);
private:
std::queue<T>& _q;
;
Used like this:
std::queue<int> qi;
QueueAdapter< std::queue<int> > qiqa( qi );
std::copy( v.begin(), v.end(), std::back_inserter( qiqa ) );
Unfortunately std::queue 'adapts' the function known as push_back to just push which means that the standard back_insert_iterator doesn't work.
Probably the simplest way (albeit conceptually ugly) is to adapt the container adapter with a short lived container adapter adapter[sic] (eugh!) that lives as long as the back insert iterator.
template<class T>
class QueueAdapter
public:
QueueAdapter(std::queue<T>& q) : _q(q)
void push_back(const T& t) _q.push(t);
private:
std::queue<T>& _q;
;
Used like this:
std::queue<int> qi;
QueueAdapter< std::queue<int> > qiqa( qi );
std::copy( v.begin(), v.end(), std::back_inserter( qiqa ) );
answered Nov 12 '09 at 16:58
CB BaileyCB Bailey
523k78559614
523k78559614
3
Genius. Neat, beautiful, and exposes the odd decision to use the name push instead of push_back in the first place.
– Andy Balaam
Nov 12 '09 at 17:00
2
It's notpush_back, because the point where the insertions happen don't matter conceptually. Besides, what wouldpush_backmean for apriority_queue?
– UncleBens
Nov 12 '09 at 17:24
1
Conceptually it makes sense, I just used the work 'unfortunately' because it means that it closes off using theback_insert_iteratorwhich could be really useful.
– CB Bailey
Nov 12 '09 at 17:32
I agree with Kylotan's comment to the question. If you want to do things beyond what the queue ADT allows (basically pushing and popping), there's little point fighting the queue adaptor. - +1 to your elegant answer, though.
– UncleBens
Nov 12 '09 at 20:34
add a comment |
3
Genius. Neat, beautiful, and exposes the odd decision to use the name push instead of push_back in the first place.
– Andy Balaam
Nov 12 '09 at 17:00
2
It's notpush_back, because the point where the insertions happen don't matter conceptually. Besides, what wouldpush_backmean for apriority_queue?
– UncleBens
Nov 12 '09 at 17:24
1
Conceptually it makes sense, I just used the work 'unfortunately' because it means that it closes off using theback_insert_iteratorwhich could be really useful.
– CB Bailey
Nov 12 '09 at 17:32
I agree with Kylotan's comment to the question. If you want to do things beyond what the queue ADT allows (basically pushing and popping), there's little point fighting the queue adaptor. - +1 to your elegant answer, though.
– UncleBens
Nov 12 '09 at 20:34
3
3
Genius. Neat, beautiful, and exposes the odd decision to use the name push instead of push_back in the first place.
– Andy Balaam
Nov 12 '09 at 17:00
Genius. Neat, beautiful, and exposes the odd decision to use the name push instead of push_back in the first place.
– Andy Balaam
Nov 12 '09 at 17:00
2
2
It's not
push_back, because the point where the insertions happen don't matter conceptually. Besides, what would push_back mean for a priority_queue?– UncleBens
Nov 12 '09 at 17:24
It's not
push_back, because the point where the insertions happen don't matter conceptually. Besides, what would push_back mean for a priority_queue?– UncleBens
Nov 12 '09 at 17:24
1
1
Conceptually it makes sense, I just used the work 'unfortunately' because it means that it closes off using the
back_insert_iterator which could be really useful.– CB Bailey
Nov 12 '09 at 17:32
Conceptually it makes sense, I just used the work 'unfortunately' because it means that it closes off using the
back_insert_iterator which could be really useful.– CB Bailey
Nov 12 '09 at 17:32
I agree with Kylotan's comment to the question. If you want to do things beyond what the queue ADT allows (basically pushing and popping), there's little point fighting the queue adaptor. - +1 to your elegant answer, though.
– UncleBens
Nov 12 '09 at 20:34
I agree with Kylotan's comment to the question. If you want to do things beyond what the queue ADT allows (basically pushing and popping), there's little point fighting the queue adaptor. - +1 to your elegant answer, though.
– UncleBens
Nov 12 '09 at 20:34
add a comment |
Queue does not allow iteration through its elements.
From the SGI STL Docs:
A queue is an adaptor that provides a
restricted subset of Container
functionality A queue is a "first in
first out" (FIFO) data structure. 1
That is, elements are added to the
back of the queue and may be removed
from the front; Q.front() is the
element that was added to the queue
least recently. Queue does not allow
iteration through its elements. [2]
You can make this work, but you can't use insert_iterator. You'll have to write something like queue_inserter that presents an iterator interface.
Update I couldn't help myself and deicded to try to implement the iterator you need. Here are the results:
template< typename T, typename U >
class queue_inserter
queue<T, U> &qu;
public:
queue_inserter(queue<T,U> &q) : qu(q)
queue_inserter<T,U> operator ++ (int) return *this;
queue_inserter<T,U> operator * () return *this;
void operator = (const T &val) qu.push(val);
;
template< typename T, typename U >
queue_inserter<T,U> make_queue_inserter(queue<T,U> &q)
return queue_inserter<T,U>(q);
This works great for functions like this:
template<typename II, typename OI>
void mycopy(II b, II e, OI oi)
while (b != e) *oi++ = *b++;
But it doesn't work with the STL copy because the STL is stupid.
1
Andy isn't trying to iteratoe through the queue, but to append to it.
– sbi
Nov 12 '09 at 16:42
1
Otherwise your answer is reasonable, though.:)+1
– sbi
Nov 12 '09 at 16:44
2
Why not implement the queue_inserter to correspond to the back_insert_iterator interface?std::copyisn't 'stupid' (IMHO!), it just requires an output iterator which isn't an onerous interface.
– CB Bailey
Nov 12 '09 at 17:48
4
Your queue_inserter isn't assignable, but apart from that you don't have to derive fromiterator, you only have to provide a specialization foriterator_traitsif you want to able to use your iterator with standard algorithms.
– CB Bailey
Nov 12 '09 at 20:28
2
BTW,std::copyin particular commonly needs to know more about the iterators, so it can pick an optimal way to do it: e.g pointers + PODs can be memmoved.
– UncleBens
Nov 12 '09 at 23:05
|
show 4 more comments
Queue does not allow iteration through its elements.
From the SGI STL Docs:
A queue is an adaptor that provides a
restricted subset of Container
functionality A queue is a "first in
first out" (FIFO) data structure. 1
That is, elements are added to the
back of the queue and may be removed
from the front; Q.front() is the
element that was added to the queue
least recently. Queue does not allow
iteration through its elements. [2]
You can make this work, but you can't use insert_iterator. You'll have to write something like queue_inserter that presents an iterator interface.
Update I couldn't help myself and deicded to try to implement the iterator you need. Here are the results:
template< typename T, typename U >
class queue_inserter
queue<T, U> &qu;
public:
queue_inserter(queue<T,U> &q) : qu(q)
queue_inserter<T,U> operator ++ (int) return *this;
queue_inserter<T,U> operator * () return *this;
void operator = (const T &val) qu.push(val);
;
template< typename T, typename U >
queue_inserter<T,U> make_queue_inserter(queue<T,U> &q)
return queue_inserter<T,U>(q);
This works great for functions like this:
template<typename II, typename OI>
void mycopy(II b, II e, OI oi)
while (b != e) *oi++ = *b++;
But it doesn't work with the STL copy because the STL is stupid.
1
Andy isn't trying to iteratoe through the queue, but to append to it.
– sbi
Nov 12 '09 at 16:42
1
Otherwise your answer is reasonable, though.:)+1
– sbi
Nov 12 '09 at 16:44
2
Why not implement the queue_inserter to correspond to the back_insert_iterator interface?std::copyisn't 'stupid' (IMHO!), it just requires an output iterator which isn't an onerous interface.
– CB Bailey
Nov 12 '09 at 17:48
4
Your queue_inserter isn't assignable, but apart from that you don't have to derive fromiterator, you only have to provide a specialization foriterator_traitsif you want to able to use your iterator with standard algorithms.
– CB Bailey
Nov 12 '09 at 20:28
2
BTW,std::copyin particular commonly needs to know more about the iterators, so it can pick an optimal way to do it: e.g pointers + PODs can be memmoved.
– UncleBens
Nov 12 '09 at 23:05
|
show 4 more comments
Queue does not allow iteration through its elements.
From the SGI STL Docs:
A queue is an adaptor that provides a
restricted subset of Container
functionality A queue is a "first in
first out" (FIFO) data structure. 1
That is, elements are added to the
back of the queue and may be removed
from the front; Q.front() is the
element that was added to the queue
least recently. Queue does not allow
iteration through its elements. [2]
You can make this work, but you can't use insert_iterator. You'll have to write something like queue_inserter that presents an iterator interface.
Update I couldn't help myself and deicded to try to implement the iterator you need. Here are the results:
template< typename T, typename U >
class queue_inserter
queue<T, U> &qu;
public:
queue_inserter(queue<T,U> &q) : qu(q)
queue_inserter<T,U> operator ++ (int) return *this;
queue_inserter<T,U> operator * () return *this;
void operator = (const T &val) qu.push(val);
;
template< typename T, typename U >
queue_inserter<T,U> make_queue_inserter(queue<T,U> &q)
return queue_inserter<T,U>(q);
This works great for functions like this:
template<typename II, typename OI>
void mycopy(II b, II e, OI oi)
while (b != e) *oi++ = *b++;
But it doesn't work with the STL copy because the STL is stupid.
Queue does not allow iteration through its elements.
From the SGI STL Docs:
A queue is an adaptor that provides a
restricted subset of Container
functionality A queue is a "first in
first out" (FIFO) data structure. 1
That is, elements are added to the
back of the queue and may be removed
from the front; Q.front() is the
element that was added to the queue
least recently. Queue does not allow
iteration through its elements. [2]
You can make this work, but you can't use insert_iterator. You'll have to write something like queue_inserter that presents an iterator interface.
Update I couldn't help myself and deicded to try to implement the iterator you need. Here are the results:
template< typename T, typename U >
class queue_inserter
queue<T, U> &qu;
public:
queue_inserter(queue<T,U> &q) : qu(q)
queue_inserter<T,U> operator ++ (int) return *this;
queue_inserter<T,U> operator * () return *this;
void operator = (const T &val) qu.push(val);
;
template< typename T, typename U >
queue_inserter<T,U> make_queue_inserter(queue<T,U> &q)
return queue_inserter<T,U>(q);
This works great for functions like this:
template<typename II, typename OI>
void mycopy(II b, II e, OI oi)
while (b != e) *oi++ = *b++;
But it doesn't work with the STL copy because the STL is stupid.
edited Nov 12 '09 at 17:40
answered Nov 12 '09 at 16:38
Frank KruegerFrank Krueger
45.1k41144198
45.1k41144198
1
Andy isn't trying to iteratoe through the queue, but to append to it.
– sbi
Nov 12 '09 at 16:42
1
Otherwise your answer is reasonable, though.:)+1
– sbi
Nov 12 '09 at 16:44
2
Why not implement the queue_inserter to correspond to the back_insert_iterator interface?std::copyisn't 'stupid' (IMHO!), it just requires an output iterator which isn't an onerous interface.
– CB Bailey
Nov 12 '09 at 17:48
4
Your queue_inserter isn't assignable, but apart from that you don't have to derive fromiterator, you only have to provide a specialization foriterator_traitsif you want to able to use your iterator with standard algorithms.
– CB Bailey
Nov 12 '09 at 20:28
2
BTW,std::copyin particular commonly needs to know more about the iterators, so it can pick an optimal way to do it: e.g pointers + PODs can be memmoved.
– UncleBens
Nov 12 '09 at 23:05
|
show 4 more comments
1
Andy isn't trying to iteratoe through the queue, but to append to it.
– sbi
Nov 12 '09 at 16:42
1
Otherwise your answer is reasonable, though.:)+1
– sbi
Nov 12 '09 at 16:44
2
Why not implement the queue_inserter to correspond to the back_insert_iterator interface?std::copyisn't 'stupid' (IMHO!), it just requires an output iterator which isn't an onerous interface.
– CB Bailey
Nov 12 '09 at 17:48
4
Your queue_inserter isn't assignable, but apart from that you don't have to derive fromiterator, you only have to provide a specialization foriterator_traitsif you want to able to use your iterator with standard algorithms.
– CB Bailey
Nov 12 '09 at 20:28
2
BTW,std::copyin particular commonly needs to know more about the iterators, so it can pick an optimal way to do it: e.g pointers + PODs can be memmoved.
– UncleBens
Nov 12 '09 at 23:05
1
1
Andy isn't trying to iteratoe through the queue, but to append to it.
– sbi
Nov 12 '09 at 16:42
Andy isn't trying to iteratoe through the queue, but to append to it.
– sbi
Nov 12 '09 at 16:42
1
1
Otherwise your answer is reasonable, though.
:) +1– sbi
Nov 12 '09 at 16:44
Otherwise your answer is reasonable, though.
:) +1– sbi
Nov 12 '09 at 16:44
2
2
Why not implement the queue_inserter to correspond to the back_insert_iterator interface?
std::copy isn't 'stupid' (IMHO!), it just requires an output iterator which isn't an onerous interface.– CB Bailey
Nov 12 '09 at 17:48
Why not implement the queue_inserter to correspond to the back_insert_iterator interface?
std::copy isn't 'stupid' (IMHO!), it just requires an output iterator which isn't an onerous interface.– CB Bailey
Nov 12 '09 at 17:48
4
4
Your queue_inserter isn't assignable, but apart from that you don't have to derive from
iterator, you only have to provide a specialization for iterator_traits if you want to able to use your iterator with standard algorithms.– CB Bailey
Nov 12 '09 at 20:28
Your queue_inserter isn't assignable, but apart from that you don't have to derive from
iterator, you only have to provide a specialization for iterator_traits if you want to able to use your iterator with standard algorithms.– CB Bailey
Nov 12 '09 at 20:28
2
2
BTW,
std::copy in particular commonly needs to know more about the iterators, so it can pick an optimal way to do it: e.g pointers + PODs can be memmoved.– UncleBens
Nov 12 '09 at 23:05
BTW,
std::copy in particular commonly needs to know more about the iterators, so it can pick an optimal way to do it: e.g pointers + PODs can be memmoved.– UncleBens
Nov 12 '09 at 23:05
|
show 4 more comments
std::queue isn't a container in the STL sense, it's a container adapter with very limited functionality. For what you seem to need either std::vector or std::deque ("double-ended queue, which is a "real container"), seems the right choice.
Or use a for loop to push into the queue. What I'm doing doesn't seem unreasonable, though, does it?
– Andy Balaam
Nov 12 '09 at 16:37
Not it isn't. See Frank's answer as to how to achieve what you want.
– sbi
Nov 12 '09 at 16:43
No it does not (functionally), but you will have to roll your own inserter unfortunately.
– Matthieu M.
Nov 12 '09 at 16:44
add a comment |
std::queue isn't a container in the STL sense, it's a container adapter with very limited functionality. For what you seem to need either std::vector or std::deque ("double-ended queue, which is a "real container"), seems the right choice.
Or use a for loop to push into the queue. What I'm doing doesn't seem unreasonable, though, does it?
– Andy Balaam
Nov 12 '09 at 16:37
Not it isn't. See Frank's answer as to how to achieve what you want.
– sbi
Nov 12 '09 at 16:43
No it does not (functionally), but you will have to roll your own inserter unfortunately.
– Matthieu M.
Nov 12 '09 at 16:44
add a comment |
std::queue isn't a container in the STL sense, it's a container adapter with very limited functionality. For what you seem to need either std::vector or std::deque ("double-ended queue, which is a "real container"), seems the right choice.
std::queue isn't a container in the STL sense, it's a container adapter with very limited functionality. For what you seem to need either std::vector or std::deque ("double-ended queue, which is a "real container"), seems the right choice.
answered Nov 12 '09 at 16:34
sbisbi
167k40217401
167k40217401
Or use a for loop to push into the queue. What I'm doing doesn't seem unreasonable, though, does it?
– Andy Balaam
Nov 12 '09 at 16:37
Not it isn't. See Frank's answer as to how to achieve what you want.
– sbi
Nov 12 '09 at 16:43
No it does not (functionally), but you will have to roll your own inserter unfortunately.
– Matthieu M.
Nov 12 '09 at 16:44
add a comment |
Or use a for loop to push into the queue. What I'm doing doesn't seem unreasonable, though, does it?
– Andy Balaam
Nov 12 '09 at 16:37
Not it isn't. See Frank's answer as to how to achieve what you want.
– sbi
Nov 12 '09 at 16:43
No it does not (functionally), but you will have to roll your own inserter unfortunately.
– Matthieu M.
Nov 12 '09 at 16:44
Or use a for loop to push into the queue. What I'm doing doesn't seem unreasonable, though, does it?
– Andy Balaam
Nov 12 '09 at 16:37
Or use a for loop to push into the queue. What I'm doing doesn't seem unreasonable, though, does it?
– Andy Balaam
Nov 12 '09 at 16:37
Not it isn't. See Frank's answer as to how to achieve what you want.
– sbi
Nov 12 '09 at 16:43
Not it isn't. See Frank's answer as to how to achieve what you want.
– sbi
Nov 12 '09 at 16:43
No it does not (functionally), but you will have to roll your own inserter unfortunately.
– Matthieu M.
Nov 12 '09 at 16:44
No it does not (functionally), but you will have to roll your own inserter unfortunately.
– Matthieu M.
Nov 12 '09 at 16:44
add a comment |
I'm pretty sure it just won't work -- a queue provides push, but an insert iterator expects to use push_front or push_back. There's no real reason you couldn't write your own push_insert_iterator (or whatever name you prefer) but it is a bit of a pain...
add a comment |
I'm pretty sure it just won't work -- a queue provides push, but an insert iterator expects to use push_front or push_back. There's no real reason you couldn't write your own push_insert_iterator (or whatever name you prefer) but it is a bit of a pain...
add a comment |
I'm pretty sure it just won't work -- a queue provides push, but an insert iterator expects to use push_front or push_back. There's no real reason you couldn't write your own push_insert_iterator (or whatever name you prefer) but it is a bit of a pain...
I'm pretty sure it just won't work -- a queue provides push, but an insert iterator expects to use push_front or push_back. There's no real reason you couldn't write your own push_insert_iterator (or whatever name you prefer) but it is a bit of a pain...
answered Nov 12 '09 at 16:43
Jerry CoffinJerry Coffin
389k50475920
389k50475920
add a comment |
add a comment |
insert_iterator and back_insert_iterator only work on containers (or adaptors) with (respectively) insert and push_back methods - queue doesn't have these. You could write your own iterator modelled on these, something like this:
template <typename Container>
class push_iterator : public iterator<output_iterator_tag,void,void,void,void>
public:
explicit push_iterator(Container &c) : container(c)
push_iterator &operator*() return *this;
push_iterator &operator++() return *this;
push_iterator &operator++(int) return *this;
push_iterator &operator=(typename Container::const_reference value)
container.push(value);
return *this;
private:
Container &container;
;
Unless such a thing already exists, but I'm pretty sure it doesn't.
I was just about to accept this answer, which looks excellent (although I haven't tried it) but Charles pipped you at the post.
– Andy Balaam
Nov 12 '09 at 17:01
It would be nice to have such an iterator in the Standard Library. However, regarding your implementation, I think it would be safer to have the dereferencing operator return a proxy object instead of the current object. Indeed, the code as it is allows you to dopush_iterator< queue< int > > it; it = 42;, which is wrong (it also allows you to do******it, which is not more correct). Theoperator*should return an object defining theoperator=.
– Luc Touraille
Nov 17 '11 at 14:30
You could also add to your answer the usual helper function allowing one to omit the container type:template < typename Container > push_iterator< Container > pusher( Container & c ) return push_iterator< Container >( c );.
– Luc Touraille
Nov 17 '11 at 14:32
add a comment |
insert_iterator and back_insert_iterator only work on containers (or adaptors) with (respectively) insert and push_back methods - queue doesn't have these. You could write your own iterator modelled on these, something like this:
template <typename Container>
class push_iterator : public iterator<output_iterator_tag,void,void,void,void>
public:
explicit push_iterator(Container &c) : container(c)
push_iterator &operator*() return *this;
push_iterator &operator++() return *this;
push_iterator &operator++(int) return *this;
push_iterator &operator=(typename Container::const_reference value)
container.push(value);
return *this;
private:
Container &container;
;
Unless such a thing already exists, but I'm pretty sure it doesn't.
I was just about to accept this answer, which looks excellent (although I haven't tried it) but Charles pipped you at the post.
– Andy Balaam
Nov 12 '09 at 17:01
It would be nice to have such an iterator in the Standard Library. However, regarding your implementation, I think it would be safer to have the dereferencing operator return a proxy object instead of the current object. Indeed, the code as it is allows you to dopush_iterator< queue< int > > it; it = 42;, which is wrong (it also allows you to do******it, which is not more correct). Theoperator*should return an object defining theoperator=.
– Luc Touraille
Nov 17 '11 at 14:30
You could also add to your answer the usual helper function allowing one to omit the container type:template < typename Container > push_iterator< Container > pusher( Container & c ) return push_iterator< Container >( c );.
– Luc Touraille
Nov 17 '11 at 14:32
add a comment |
insert_iterator and back_insert_iterator only work on containers (or adaptors) with (respectively) insert and push_back methods - queue doesn't have these. You could write your own iterator modelled on these, something like this:
template <typename Container>
class push_iterator : public iterator<output_iterator_tag,void,void,void,void>
public:
explicit push_iterator(Container &c) : container(c)
push_iterator &operator*() return *this;
push_iterator &operator++() return *this;
push_iterator &operator++(int) return *this;
push_iterator &operator=(typename Container::const_reference value)
container.push(value);
return *this;
private:
Container &container;
;
Unless such a thing already exists, but I'm pretty sure it doesn't.
insert_iterator and back_insert_iterator only work on containers (or adaptors) with (respectively) insert and push_back methods - queue doesn't have these. You could write your own iterator modelled on these, something like this:
template <typename Container>
class push_iterator : public iterator<output_iterator_tag,void,void,void,void>
public:
explicit push_iterator(Container &c) : container(c)
push_iterator &operator*() return *this;
push_iterator &operator++() return *this;
push_iterator &operator++(int) return *this;
push_iterator &operator=(typename Container::const_reference value)
container.push(value);
return *this;
private:
Container &container;
;
Unless such a thing already exists, but I'm pretty sure it doesn't.
answered Nov 12 '09 at 16:55
Mike SeymourMike Seymour
216k20344559
216k20344559
I was just about to accept this answer, which looks excellent (although I haven't tried it) but Charles pipped you at the post.
– Andy Balaam
Nov 12 '09 at 17:01
It would be nice to have such an iterator in the Standard Library. However, regarding your implementation, I think it would be safer to have the dereferencing operator return a proxy object instead of the current object. Indeed, the code as it is allows you to dopush_iterator< queue< int > > it; it = 42;, which is wrong (it also allows you to do******it, which is not more correct). Theoperator*should return an object defining theoperator=.
– Luc Touraille
Nov 17 '11 at 14:30
You could also add to your answer the usual helper function allowing one to omit the container type:template < typename Container > push_iterator< Container > pusher( Container & c ) return push_iterator< Container >( c );.
– Luc Touraille
Nov 17 '11 at 14:32
add a comment |
I was just about to accept this answer, which looks excellent (although I haven't tried it) but Charles pipped you at the post.
– Andy Balaam
Nov 12 '09 at 17:01
It would be nice to have such an iterator in the Standard Library. However, regarding your implementation, I think it would be safer to have the dereferencing operator return a proxy object instead of the current object. Indeed, the code as it is allows you to dopush_iterator< queue< int > > it; it = 42;, which is wrong (it also allows you to do******it, which is not more correct). Theoperator*should return an object defining theoperator=.
– Luc Touraille
Nov 17 '11 at 14:30
You could also add to your answer the usual helper function allowing one to omit the container type:template < typename Container > push_iterator< Container > pusher( Container & c ) return push_iterator< Container >( c );.
– Luc Touraille
Nov 17 '11 at 14:32
I was just about to accept this answer, which looks excellent (although I haven't tried it) but Charles pipped you at the post.
– Andy Balaam
Nov 12 '09 at 17:01
I was just about to accept this answer, which looks excellent (although I haven't tried it) but Charles pipped you at the post.
– Andy Balaam
Nov 12 '09 at 17:01
It would be nice to have such an iterator in the Standard Library. However, regarding your implementation, I think it would be safer to have the dereferencing operator return a proxy object instead of the current object. Indeed, the code as it is allows you to do
push_iterator< queue< int > > it; it = 42;, which is wrong (it also allows you to do ******it, which is not more correct). The operator* should return an object defining the operator=.– Luc Touraille
Nov 17 '11 at 14:30
It would be nice to have such an iterator in the Standard Library. However, regarding your implementation, I think it would be safer to have the dereferencing operator return a proxy object instead of the current object. Indeed, the code as it is allows you to do
push_iterator< queue< int > > it; it = 42;, which is wrong (it also allows you to do ******it, which is not more correct). The operator* should return an object defining the operator=.– Luc Touraille
Nov 17 '11 at 14:30
You could also add to your answer the usual helper function allowing one to omit the container type:
template < typename Container > push_iterator< Container > pusher( Container & c ) return push_iterator< Container >( c ); .– Luc Touraille
Nov 17 '11 at 14:32
You could also add to your answer the usual helper function allowing one to omit the container type:
template < typename Container > push_iterator< Container > pusher( Container & c ) return push_iterator< Container >( c ); .– Luc Touraille
Nov 17 '11 at 14:32
add a comment |
What you need is a push_inserter (i.e. an inserter that performs pushes into the queue). As far as I know, there is no such iterator in the STL. What I usually do is sadly fall back to the good old for loop.
If you have the courage, you can roll your own iterator, something along these lines:
template <typename Container>
class push_insert_iterator
public:
typedef Container container_type;
typedef typename Container::value_type value_type;
explicit push_insert_iterator(container_type & c)
: container(c)
// construct with container
push_insert_iterator<container_type> & operator=(const value_type & v)
//push value into the queue
container.push(v);
return (*this);
push_insert_iterator<container_type> & operator*()
return (*this);
push_insert_iterator<container_type> & operator++()
// Do nothing
return (*this);
push_insert_iterator<container_type> operator++(int)
// Do nothing
return (*this);
protected:
container_type & container; // reference to container
;
template <typename Container>
inline push_insert_iterator<Container> push_inserter(Container & c)
return push_insert_iterator<Container>(c);
This is just a draft but you got the idea. Works with any container (or, well, container adapters) with a push method (e.g. queue, stack).
It's called "back inserter" in the STL and you get one fromback_inserter. However, this doesn't work onstd::queue.
– sbi
Nov 12 '09 at 16:41
1
I know what a back_insert_iterator is: an iterator that performs push_back into a container. Queue does not have a push_back method, that is why back_insert_iterator doesn't work. The method for adding elements in a queue is push, hence the push_insert_iterator idea...
– Luc Touraille
Nov 12 '09 at 16:44
@sbi: Considering that "inserting" an element into a queue is made via the queue::push() function,push_inserteris not a bad name, IMHO
– Éric Malenfant
Nov 12 '09 at 16:50
@Éric: No, it isn't. Not at all. However, my comment was written before Luc's answer ever had apush_inserter.:)
– sbi
Nov 12 '09 at 23:36
add a comment |
What you need is a push_inserter (i.e. an inserter that performs pushes into the queue). As far as I know, there is no such iterator in the STL. What I usually do is sadly fall back to the good old for loop.
If you have the courage, you can roll your own iterator, something along these lines:
template <typename Container>
class push_insert_iterator
public:
typedef Container container_type;
typedef typename Container::value_type value_type;
explicit push_insert_iterator(container_type & c)
: container(c)
// construct with container
push_insert_iterator<container_type> & operator=(const value_type & v)
//push value into the queue
container.push(v);
return (*this);
push_insert_iterator<container_type> & operator*()
return (*this);
push_insert_iterator<container_type> & operator++()
// Do nothing
return (*this);
push_insert_iterator<container_type> operator++(int)
// Do nothing
return (*this);
protected:
container_type & container; // reference to container
;
template <typename Container>
inline push_insert_iterator<Container> push_inserter(Container & c)
return push_insert_iterator<Container>(c);
This is just a draft but you got the idea. Works with any container (or, well, container adapters) with a push method (e.g. queue, stack).
It's called "back inserter" in the STL and you get one fromback_inserter. However, this doesn't work onstd::queue.
– sbi
Nov 12 '09 at 16:41
1
I know what a back_insert_iterator is: an iterator that performs push_back into a container. Queue does not have a push_back method, that is why back_insert_iterator doesn't work. The method for adding elements in a queue is push, hence the push_insert_iterator idea...
– Luc Touraille
Nov 12 '09 at 16:44
@sbi: Considering that "inserting" an element into a queue is made via the queue::push() function,push_inserteris not a bad name, IMHO
– Éric Malenfant
Nov 12 '09 at 16:50
@Éric: No, it isn't. Not at all. However, my comment was written before Luc's answer ever had apush_inserter.:)
– sbi
Nov 12 '09 at 23:36
add a comment |
What you need is a push_inserter (i.e. an inserter that performs pushes into the queue). As far as I know, there is no such iterator in the STL. What I usually do is sadly fall back to the good old for loop.
If you have the courage, you can roll your own iterator, something along these lines:
template <typename Container>
class push_insert_iterator
public:
typedef Container container_type;
typedef typename Container::value_type value_type;
explicit push_insert_iterator(container_type & c)
: container(c)
// construct with container
push_insert_iterator<container_type> & operator=(const value_type & v)
//push value into the queue
container.push(v);
return (*this);
push_insert_iterator<container_type> & operator*()
return (*this);
push_insert_iterator<container_type> & operator++()
// Do nothing
return (*this);
push_insert_iterator<container_type> operator++(int)
// Do nothing
return (*this);
protected:
container_type & container; // reference to container
;
template <typename Container>
inline push_insert_iterator<Container> push_inserter(Container & c)
return push_insert_iterator<Container>(c);
This is just a draft but you got the idea. Works with any container (or, well, container adapters) with a push method (e.g. queue, stack).
What you need is a push_inserter (i.e. an inserter that performs pushes into the queue). As far as I know, there is no such iterator in the STL. What I usually do is sadly fall back to the good old for loop.
If you have the courage, you can roll your own iterator, something along these lines:
template <typename Container>
class push_insert_iterator
public:
typedef Container container_type;
typedef typename Container::value_type value_type;
explicit push_insert_iterator(container_type & c)
: container(c)
// construct with container
push_insert_iterator<container_type> & operator=(const value_type & v)
//push value into the queue
container.push(v);
return (*this);
push_insert_iterator<container_type> & operator*()
return (*this);
push_insert_iterator<container_type> & operator++()
// Do nothing
return (*this);
push_insert_iterator<container_type> operator++(int)
// Do nothing
return (*this);
protected:
container_type & container; // reference to container
;
template <typename Container>
inline push_insert_iterator<Container> push_inserter(Container & c)
return push_insert_iterator<Container>(c);
This is just a draft but you got the idea. Works with any container (or, well, container adapters) with a push method (e.g. queue, stack).
edited Nov 12 '09 at 17:10
answered Nov 12 '09 at 16:40
Luc TourailleLuc Touraille
60.9k1172129
60.9k1172129
It's called "back inserter" in the STL and you get one fromback_inserter. However, this doesn't work onstd::queue.
– sbi
Nov 12 '09 at 16:41
1
I know what a back_insert_iterator is: an iterator that performs push_back into a container. Queue does not have a push_back method, that is why back_insert_iterator doesn't work. The method for adding elements in a queue is push, hence the push_insert_iterator idea...
– Luc Touraille
Nov 12 '09 at 16:44
@sbi: Considering that "inserting" an element into a queue is made via the queue::push() function,push_inserteris not a bad name, IMHO
– Éric Malenfant
Nov 12 '09 at 16:50
@Éric: No, it isn't. Not at all. However, my comment was written before Luc's answer ever had apush_inserter.:)
– sbi
Nov 12 '09 at 23:36
add a comment |
It's called "back inserter" in the STL and you get one fromback_inserter. However, this doesn't work onstd::queue.
– sbi
Nov 12 '09 at 16:41
1
I know what a back_insert_iterator is: an iterator that performs push_back into a container. Queue does not have a push_back method, that is why back_insert_iterator doesn't work. The method for adding elements in a queue is push, hence the push_insert_iterator idea...
– Luc Touraille
Nov 12 '09 at 16:44
@sbi: Considering that "inserting" an element into a queue is made via the queue::push() function,push_inserteris not a bad name, IMHO
– Éric Malenfant
Nov 12 '09 at 16:50
@Éric: No, it isn't. Not at all. However, my comment was written before Luc's answer ever had apush_inserter.:)
– sbi
Nov 12 '09 at 23:36
It's called "back inserter" in the STL and you get one from
back_inserter. However, this doesn't work on std::queue.– sbi
Nov 12 '09 at 16:41
It's called "back inserter" in the STL and you get one from
back_inserter. However, this doesn't work on std::queue.– sbi
Nov 12 '09 at 16:41
1
1
I know what a back_insert_iterator is: an iterator that performs push_back into a container. Queue does not have a push_back method, that is why back_insert_iterator doesn't work. The method for adding elements in a queue is push, hence the push_insert_iterator idea...
– Luc Touraille
Nov 12 '09 at 16:44
I know what a back_insert_iterator is: an iterator that performs push_back into a container. Queue does not have a push_back method, that is why back_insert_iterator doesn't work. The method for adding elements in a queue is push, hence the push_insert_iterator idea...
– Luc Touraille
Nov 12 '09 at 16:44
@sbi: Considering that "inserting" an element into a queue is made via the queue::push() function,
push_inserter is not a bad name, IMHO– Éric Malenfant
Nov 12 '09 at 16:50
@sbi: Considering that "inserting" an element into a queue is made via the queue::push() function,
push_inserter is not a bad name, IMHO– Éric Malenfant
Nov 12 '09 at 16:50
@Éric: No, it isn't. Not at all. However, my comment was written before Luc's answer ever had a
push_inserter. :)– sbi
Nov 12 '09 at 23:36
@Éric: No, it isn't. Not at all. However, my comment was written before Luc's answer ever had a
push_inserter. :)– sbi
Nov 12 '09 at 23:36
add a comment |
std::queue is not one of the basic containers in STL. It is a container adaptor which is built using one of the basic STL containers ( in this case one of the sequential container either std::vector std::deque or std::list). It is designed specifically for FIFO behaviour and does not provide random insertion at the given iterator which you want for the insert_iterator to work. Hence it will not be possible to use queue like this.
The easiest way I could think of to do this is to:
class PushFunctor
public:
PushFunctor(std::queue<int>& q) : myQ(q)
void operator()(int n)
myQ.push(n);
private:
std::queue<int>& myQ;
;
And use it like:
queue<int> q;
PushFunctor p(q);
std::for_each(v.begin(), v.end(), p);
This is also a great idea.
– Andy Balaam
Nov 12 '09 at 17:02
add a comment |
std::queue is not one of the basic containers in STL. It is a container adaptor which is built using one of the basic STL containers ( in this case one of the sequential container either std::vector std::deque or std::list). It is designed specifically for FIFO behaviour and does not provide random insertion at the given iterator which you want for the insert_iterator to work. Hence it will not be possible to use queue like this.
The easiest way I could think of to do this is to:
class PushFunctor
public:
PushFunctor(std::queue<int>& q) : myQ(q)
void operator()(int n)
myQ.push(n);
private:
std::queue<int>& myQ;
;
And use it like:
queue<int> q;
PushFunctor p(q);
std::for_each(v.begin(), v.end(), p);
This is also a great idea.
– Andy Balaam
Nov 12 '09 at 17:02
add a comment |
std::queue is not one of the basic containers in STL. It is a container adaptor which is built using one of the basic STL containers ( in this case one of the sequential container either std::vector std::deque or std::list). It is designed specifically for FIFO behaviour and does not provide random insertion at the given iterator which you want for the insert_iterator to work. Hence it will not be possible to use queue like this.
The easiest way I could think of to do this is to:
class PushFunctor
public:
PushFunctor(std::queue<int>& q) : myQ(q)
void operator()(int n)
myQ.push(n);
private:
std::queue<int>& myQ;
;
And use it like:
queue<int> q;
PushFunctor p(q);
std::for_each(v.begin(), v.end(), p);
std::queue is not one of the basic containers in STL. It is a container adaptor which is built using one of the basic STL containers ( in this case one of the sequential container either std::vector std::deque or std::list). It is designed specifically for FIFO behaviour and does not provide random insertion at the given iterator which you want for the insert_iterator to work. Hence it will not be possible to use queue like this.
The easiest way I could think of to do this is to:
class PushFunctor
public:
PushFunctor(std::queue<int>& q) : myQ(q)
void operator()(int n)
myQ.push(n);
private:
std::queue<int>& myQ;
;
And use it like:
queue<int> q;
PushFunctor p(q);
std::for_each(v.begin(), v.end(), p);
edited Nov 12 '09 at 16:58
answered Nov 12 '09 at 16:41
NaveenNaveen
51.9k40149219
51.9k40149219
This is also a great idea.
– Andy Balaam
Nov 12 '09 at 17:02
add a comment |
This is also a great idea.
– Andy Balaam
Nov 12 '09 at 17:02
This is also a great idea.
– Andy Balaam
Nov 12 '09 at 17:02
This is also a great idea.
– Andy Balaam
Nov 12 '09 at 17:02
add a comment |
In this simple case, you can write:
vector<int> v;
v.push_back( 1 );
v.push_back( 2 );
queue<int, vector<int> > q(v);
This will make a copy of the vector and use it as the underlying container of the queue.
Of course, this approach won't work if you need to enqueue things after the queue has been constructed.
Very good point. Unfortunately my example was too simplified and that isn't what I want to do.
– Andy Balaam
Nov 12 '09 at 16:54
2
queue cannot use a vector. The container must supportpop_front.
– UncleBens
Nov 12 '09 at 17:06
Argh! You're right. Due to templates, my test didn't show this. Well, I guess you can still create a queue that allows you to inspectfront()andback()... :P
– Thomas
Nov 12 '09 at 20:24
add a comment |
In this simple case, you can write:
vector<int> v;
v.push_back( 1 );
v.push_back( 2 );
queue<int, vector<int> > q(v);
This will make a copy of the vector and use it as the underlying container of the queue.
Of course, this approach won't work if you need to enqueue things after the queue has been constructed.
Very good point. Unfortunately my example was too simplified and that isn't what I want to do.
– Andy Balaam
Nov 12 '09 at 16:54
2
queue cannot use a vector. The container must supportpop_front.
– UncleBens
Nov 12 '09 at 17:06
Argh! You're right. Due to templates, my test didn't show this. Well, I guess you can still create a queue that allows you to inspectfront()andback()... :P
– Thomas
Nov 12 '09 at 20:24
add a comment |
In this simple case, you can write:
vector<int> v;
v.push_back( 1 );
v.push_back( 2 );
queue<int, vector<int> > q(v);
This will make a copy of the vector and use it as the underlying container of the queue.
Of course, this approach won't work if you need to enqueue things after the queue has been constructed.
In this simple case, you can write:
vector<int> v;
v.push_back( 1 );
v.push_back( 2 );
queue<int, vector<int> > q(v);
This will make a copy of the vector and use it as the underlying container of the queue.
Of course, this approach won't work if you need to enqueue things after the queue has been constructed.
answered Nov 12 '09 at 16:48
ThomasThomas
115k34254363
115k34254363
Very good point. Unfortunately my example was too simplified and that isn't what I want to do.
– Andy Balaam
Nov 12 '09 at 16:54
2
queue cannot use a vector. The container must supportpop_front.
– UncleBens
Nov 12 '09 at 17:06
Argh! You're right. Due to templates, my test didn't show this. Well, I guess you can still create a queue that allows you to inspectfront()andback()... :P
– Thomas
Nov 12 '09 at 20:24
add a comment |
Very good point. Unfortunately my example was too simplified and that isn't what I want to do.
– Andy Balaam
Nov 12 '09 at 16:54
2
queue cannot use a vector. The container must supportpop_front.
– UncleBens
Nov 12 '09 at 17:06
Argh! You're right. Due to templates, my test didn't show this. Well, I guess you can still create a queue that allows you to inspectfront()andback()... :P
– Thomas
Nov 12 '09 at 20:24
Very good point. Unfortunately my example was too simplified and that isn't what I want to do.
– Andy Balaam
Nov 12 '09 at 16:54
Very good point. Unfortunately my example was too simplified and that isn't what I want to do.
– Andy Balaam
Nov 12 '09 at 16:54
2
2
queue cannot use a vector. The container must support
pop_front.– UncleBens
Nov 12 '09 at 17:06
queue cannot use a vector. The container must support
pop_front.– UncleBens
Nov 12 '09 at 17:06
Argh! You're right. Due to templates, my test didn't show this. Well, I guess you can still create a queue that allows you to inspect
front() and back()... :P– Thomas
Nov 12 '09 at 20:24
Argh! You're right. Due to templates, my test didn't show this. Well, I guess you can still create a queue that allows you to inspect
front() and back()... :P– Thomas
Nov 12 '09 at 20:24
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f1723515%2finsert-into-an-stl-queue-using-stdcopy%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Although the answers you've been given are good, personally I would just avoid std::queue and any other crippled container adapter.
– Kylotan
Nov 12 '09 at 17:04
Yes, sbi and Naveen's suggestion to use a deque would be a good alternative.
– Andy Balaam
Nov 13 '09 at 9:23