Search code examples
c++stdpriority-queue

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 #defines 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.


Solution

  • 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.