Reputation: 7352
I'm interested in creating a function that uses a queue as part of its implementation, but I want to be templated on the type of queue so that it will have different functionality based on what type of queue its templated with.
Here's a basic example:
template <typename Queue>
void example()
{
Queue a;
a.push(3);
a.push(1);
a.push(2);
while (!a.empty()) {
cout << a.top() << ' ';
a.pop();
}
cout << flush;
}
What I want is for example<stack<int>>()
to print 2 1 3
, example<priority_queue<int>>()
to print 3 2 1
, and example<queue<int>>()
to print 3 1 2
. This works for stack
and priority_queue
but unfortunately queue
doesn't provide top
and instead provides front
. Is there an easy way to tell the compiler when it sees top
on a queue
to call front
instead?
The only way around this that I can think of is to follow this question How to implement generic method for STL containers that haven`t common interface needed for that method using template template parameter, and implement my own local top
for each of the data types and call that instead. This solution seems super inelegant though, and I'd rather find another way if possible.
Edit: I am using a compiler that supports C++11, gcc 4.7.0 to be exact.
Upvotes: 2
Views: 176
Reputation: 154015
Assuming the presence of a top()
and a front()
member are mutually exclusive, you could create a suitable top()
helper function which is overloaded on the presence of the respective member:
template <typename Queue>
auto top(Queue const& queue) -> decltype((queue.top()))
{
return queue.top();
}
template <typename Queue>
auto top(Queue const& queue) -> decltype((queue.front()))
{
return queue.front();
}
You can then just use top(a)
to access the current top even if the top is called front()
. This won't work, however, if a queue has both front()
and top()
. A simple fix to this problem is to make the choice of the front()
version just a bit less attractive to call so it is called if it is the only version but it isn't called if both top()
and front()
are available. For example:
template <typename Queue>
auto top(Queue const& queue, bool) -> decltype((queue.top()))
{
return queue.top();
}
template <typename Queue>
auto top(Queue const& queue, int) -> decltype((queue.front()))
{
return queue.front();
}
... and then get access to the top element using top(a, true)
.
Upvotes: 7