StoneThrow StoneThrow - 2 months ago 12
C++ Question

Can std::priority_queue declaration be shortened without specialization?

I hope and think this question is not a duplicate of C++ template typedef so here goes:

I'm wondering if the community can help me see if there's a way to shorten

template<typename ORDER> std::priority_queue<int, std::vector<int>, ORDER>
with a
typedef
without specializing. I'd like to discount
#define
s for this answer, please. I'm not sure if C++11's
alias
feature is applicable here, but I will also need to discount its use as an answer because the compiler I'm working with is C++03.

For context here is some sample code:

#include <iostream>
#include <queue>

namespace
{

template<typename ORDER>
std::priority_queue<int, std::vector<int>, ORDER> GetPriorityQ(std::vector<int> numbers)
{
std::priority_queue<int, std::vector<int>, ORDER> theQueue;

for (int i = 0; i < numbers.size(); ++i)
{
theQueue.push(numbers[i]);
}

return theQueue;
};

class Less
{
public:
operator()(int a, int b)
{
return (a < b);
}
};

class More
{
public:
operator()(int a, int b)
{
return (b < a);
}
};

}

int main(int argc, char* argv[])
{
std::vector<int> v({4, 9, 2, 8});

std::priority_queue<int, std::vector<int>, Less> pqLess =
GetPriorityQ<Less>(v);

std::cout << "Ordered by Less:" << std::endl;
while (!pqLess.empty())
{
std::cout << pqLess.top() << std::endl;
pqLess.pop();
}

std::priority_queue<int, std::vector<int>, More> pqMore =
GetPriorityQ<More>(v);

std::cout << "Ordered by More:" << std::endl;
while (!pqMore.empty())
{
std::cout << pqMore.top() << std::endl;
pqMore.pop();
}

return 0;
}


I'm aware that I could shorten a specialization of the priority queue with something like...

typedef std::priority_queue<int, std::vector<int>, Less> LessQueue;


...but I'm wondering if there's a way to shorten it without the specialization, so that I can keep
GetPriorityQ(...)
generic (i.e. if I specialized the typedef of the
priority_queue
, I'd have to implement as many specializations of
GetPriorityQ(...)
which I want to avoid).

I.e., in pseudocode, is there a way to do something like:

typedef std::priority_queue<int, std::vector<int>, ORDER> OrderedQ

...

template<typename ORDER>
OrderedQueue<ORDER> GetPriority(std::vector<int> numbers)
{
...
}

...

int main(int argc, char* argv[])
{
...
OrderedQueue<Less> pqLess = GetPriorityQ<Less>(v);
...
}


The reason why I ask is that the length of the line to define a
priority_queue
gets pretty long, even in this simplified example. The actual code I'm working on, which this example is a simplification of, is much longer and hence difficult to read.

Answers don't necessarily need to be
typedef
per se. Anything C++03-compatible and not using
#define
is okay.

Thank you.

Answer

For C++03 you can't avoid some verbiage, namely (in template code) typename, but apart from that:

template< class Order >
struct Pq
{
    typedef std::priority_queue<int, std::vector<int>, Order> T;
};

So now you can write e.g. Pq<OrderA>::T, which is shorter. Or, when OrderA is a template argument, typename Pq<OrderA>::T.

Disclaimer: code not touched by compiler.


In other news:

  • ALL UPPERCASE is an eyesore, and using it for anything else but macro names conflicts with the common convention for macro naming.