Thursday, November 26, 2015

Trick to iterate queue in C++

Oh shit! Iterator was not part of the queue interface, then how could I iterate the content of the queue?

While I was unit testing my code, I want to check whether the queue does contain any search string found in the queue. Thus, I have a QueuePath which storing some text and then iterate the queue with following way, it failed.
typedef queue<wstring> QueuePath;
QueuePath::iterator it;
for( it=list.begin(); it != list.end(); it++ ) {
   …
}
This will hit compilation error because an iterator isn’t a member of the queue, thus a better resolution would be to use deque. Since my earlier design was started with queue, I didn’t really want to change it for now. While searching for a solution, I had discovered the new trick in ideone.com which is to iterate the queue. This trick is a work around for the queue to support the iterator interface.
#include <deque>
#include <queue>

using namespace std;

template< typename T, typename Container=std::deque<T> >
class MyQueue : public queue<T,Container>
{
public:
	typedef typename Container::iterator iterator;

	iterator begin() { return this->c.begin(); }
	iterator end() { return this->c.end(); }
};
int _tmain(int argc, _TCHAR* argv[])
{
	MyQueue<int> q;
	for (int i = 0; i < 10; i++)
		q.push(i);

	for (auto it = q.begin(); it != q.end(); it++)
		cout << *it << endl;

	return 0;
}
Although this workaround is damn real cool, but I was so reluctant to change my code. Anyway, think about it, do I really need this just for the unit testing? Basically, I could have something like below to get my job accomplished since I’m working on the unit test.
while( !list.empty() ) {
        …
        list.pop();
}
Remember my objective? The objective of this unit test is to make sure that the content in the queue was correct.

No comments: