I'm trying to use BOOST_FOREACH for iterating through the std::queue. But there isn't iterators in that class cause I have an error:
std::queue<std::string> someList;
BOOST_FOREACH(std::string temp, someList)
{
std::cout << temp;
}
>no matching function for call to begin(...)
>no type named ‘iterator’ in ‘class std::queue<std::basic_string<char> >’
I need in structure like: the first comes, the first goes away.
std::deque supports efficient insert and removal at the beginning and end of the data structure. You can do queue operations manually using push_back and pop_front.
A queue uses a deque internally by default. It's a wrapper that only exposes queue operations (hence why you can't iterate over it). I asked a similar question a while back, and the best answer gave me good insight into the real use of std::queue. One should use std::queue not because one needs a queue, but to make it clear that only queue-like operations are legal on a given data structure. It sounds like you need more freedom than that, so go with deque, list, or some other structure with O(1) insert and remove at both ends.
you can use
std::list with push_front and pop_back
std::queue is a container adaptor. It uses std::deque as the default underlying container. Access to this container isn't possible and thus isn't iteration in any way.
The best way is to use a std::deque or std::list and manage the queue behaviour yourself. Possibly provide your own wrapper around it.
Related
I am writing a very simple std::stack using vector as its underlying container. I realized that I could replace all the push(), pop() and top() functions with push_back(), pop_back() and back() of the vector container.
My questions are: why to use a container adaptor when the controlled use of the underlying container is enough? Why not to use just a deque, vector or list? There will be waste of memory or processing time?
When your code says std::stack it's clear to the reader what operations they need on the container... it communicates and documents while enforcing that no other operations are used. It may help them quickly form an impression of the algorithmic logic in your code. It's then easy to substitute other implementations that honour the same interface.
It's a bit like using std::ifstream instead of std::fstream - you can read and write with std::fstream, but whomever reads your code will need to consider more possible uses you put the stream to before realising that it's only being used for reading; you'd be wasting their mental effort.
By reverse I mean swap the order of the elements so a stack containing ABCD ends up with DCBA. I am currently using vectors instead of stacks just because of the reverse operation.
std::stack<T> operates by wrapping an underlying container, typically std::deque<T>.
// According to cppreference.com
template<
class T,
class Container = std::deque<T>
> class stack;
There's no reason to use a std::stack instead of a std::vector or a std::deque unless all you care about is the top element. The structure doesn't even expose iterators, and that's part of the design.
Sure you can write a fancy function to reverse it (store the top, pop, push to a new stack, repeat), but why do more work than you have to?
A stack is a container that provides a nice simple push/pop/top interface. What you are asking for is actually not stack functionality so that implies that a stack is the wrong container for your needs.
Most likely either a vector or deque would be a good choice (as you have already mentioned in your question) as they provide constant time push/pop back capabilities, as well as a linear time reversal (std::reverse).
The STL stack is not a container, it's a container adapter ( http://www.cplusplus.com/reference/stack/stack/ ). The underlying container type is passed as an argument to the template, with the default being deque. The short answer to your question is 'no' -- the stack interface doesn't provide that capability.
The two options I see are:
Use the stack interface (pure stack solution) as described above (link repeated here for convenience):
http://dev-faqs.blogspot.com/2012/02/reverse-given-stack-in-place.html
Use a more flexible structure as you have done (e.g. vector or deque). In this case it probably makes the most sense to use a deque and push/pop from either end, depending on whether you're using the sequence in "forward" or "reverse" mode. That's most efficient.
Is there a way to convert a C++ STL deque to a stack, and vice versa, without iterating over each element of the source manually? (I'm not sure if one of the <cast>s are usable here.)
stack is just an container adaptor, so you can just pass deque object to it to use it as a container:
std::deque<int> my_deque;
// Do something with deque here
std::stack<int> s(my_deque);
To covert in other direction, you can use constructor with the iterators:
I am not sure if you can do the direct conversion vice-versa (other than using my_deque directly). Only thing that I can think of is following:
std::deque<int> other_deck;
// Construct new stack:
std::stack<int> new_stack(other_deck);
// use std::swap
std::swap(new_stack, old_stack);
Now the other_deck should be filled with the from the old_stack.
Exchanges the contents of the container adaptor with those of other. Effectively calls using std::swap; swap(c, other.c);
Edit It seems that swap is just swapping the underlying containers, and not the container's contents, so this will not work.
Does anyone know why std::queue, std::stack, and std::priority_queue don't provide a clear() member function? I have to fake one like this:
std::queue<int> q;
// time passes...
q = std::queue<int>(); // equivalent to clear()
IIRC, clear() is provided by everything that could serve as the underlying container. Is there a good reason to not have the container adaptors provide it?
Well, I think this is because clear was not considered a valid operation on a queue, a priority_queue or a stack (by the way, deque is not and adaptor but a container).
The only reason to use the container
adaptor queue instead of the container
deque is to make it clear that you are
performing only queue operations, and
no other operations. (from the sgi page on queue)
So when using a queue, all you can do is push/pop elements; clearing the queue can be seen as a violation of the FIFO concept. Consequently, if you need to clear your queue, maybe it's not really a queue and you should better use a deque.
However, this conception of things is a little narrow-minded, and I think clearing the queue as you do is fair enough.
Deque has clear(). See, e.g., http://www.cplusplus.com/reference/stl/deque/clear.html.
However, queue does not. But why would you choose queue over deque, anyway?
The only reason to use the container
adaptor queue instead of the container
deque is to make it clear that you are
performing only queue operations, and
no other operations.
(http://www.sgi.com/tech/stl/queue.html)
So I guess clear() is not a queue operation, then.
I'd say it's because container adaptors are not containers.
You CAN clear queues (and std::stack and priority_queue), as long as you inherit from it. The container is intentionally left protected to allow this.
#include <queue>
using namespace std;
class clearable_queue : public queue<int>
{
public:
void clear()
{
// the container 'c' in queues is intentionally left protected
c.clear();
}
};
int main(int argc, char** argv)
{
clearable_queue a;
a.clear();
}
I think it depends on the implementation - until recently Microsoft STL didn't have clear on several containers. (it does now, eg this quick google result)
However, clear() is often simply a call to erase(begin(), end()), so implement your own equivalent and use that instead.
I think the standard refers to clear as erasing over an iterator range, so the above is what most implementations will provide. (eg Dinkumware's)
std::queue, std::deque, and std::priority_queue are container adaptors and only provide a small number of methods to access the underlying container.
You can clear the underlying container, so long as you can access it. To do this, create the underlying container to pass in to the apadptor constructor. For example:
std::deque< int > d;
std::queue< int > q( d );
... time passes ...
d.clear();
Edit: additional info
I should also have warned you to tread carefully here as calling methods on the underlying container may break assumptions made by the adaptor. In that respect, the way you are currently clearng the queue seems preferable.
Does anyone know why std::queue, std::stack, and std::priority_queue don't provide a clear() member function? I have to fake one like this:
std::queue<int> q;
// time passes...
q = std::queue<int>(); // equivalent to clear()
IIRC, clear() is provided by everything that could serve as the underlying container. Is there a good reason to not have the container adaptors provide it?
Well, I think this is because clear was not considered a valid operation on a queue, a priority_queue or a stack (by the way, deque is not and adaptor but a container).
The only reason to use the container
adaptor queue instead of the container
deque is to make it clear that you are
performing only queue operations, and
no other operations. (from the sgi page on queue)
So when using a queue, all you can do is push/pop elements; clearing the queue can be seen as a violation of the FIFO concept. Consequently, if you need to clear your queue, maybe it's not really a queue and you should better use a deque.
However, this conception of things is a little narrow-minded, and I think clearing the queue as you do is fair enough.
Deque has clear(). See, e.g., http://www.cplusplus.com/reference/stl/deque/clear.html.
However, queue does not. But why would you choose queue over deque, anyway?
The only reason to use the container
adaptor queue instead of the container
deque is to make it clear that you are
performing only queue operations, and
no other operations.
(http://www.sgi.com/tech/stl/queue.html)
So I guess clear() is not a queue operation, then.
I'd say it's because container adaptors are not containers.
You CAN clear queues (and std::stack and priority_queue), as long as you inherit from it. The container is intentionally left protected to allow this.
#include <queue>
using namespace std;
class clearable_queue : public queue<int>
{
public:
void clear()
{
// the container 'c' in queues is intentionally left protected
c.clear();
}
};
int main(int argc, char** argv)
{
clearable_queue a;
a.clear();
}
I think it depends on the implementation - until recently Microsoft STL didn't have clear on several containers. (it does now, eg this quick google result)
However, clear() is often simply a call to erase(begin(), end()), so implement your own equivalent and use that instead.
I think the standard refers to clear as erasing over an iterator range, so the above is what most implementations will provide. (eg Dinkumware's)
std::queue, std::deque, and std::priority_queue are container adaptors and only provide a small number of methods to access the underlying container.
You can clear the underlying container, so long as you can access it. To do this, create the underlying container to pass in to the apadptor constructor. For example:
std::deque< int > d;
std::queue< int > q( d );
... time passes ...
d.clear();
Edit: additional info
I should also have warned you to tread carefully here as calling methods on the underlying container may break assumptions made by the adaptor. In that respect, the way you are currently clearng the queue seems preferable.