Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 3313308
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 17, 20262026-05-17T22:06:01+00:00 2026-05-17T22:06:01+00:00

I have a fairly large, sophisticated algorithm that uses a std::priority_queue . In some

  • 0

I have a fairly large, sophisticated algorithm that uses a std::priority_queue. In some cases, I want the queue to be a min-queue, and in others, a max-queue. So I have to provide a comparator type that does one or the other. Since the comparator is a template parameter, it is fundamentally part of the type of the std::priority_queue. So everywhere the queue is referenced, the code must know the type.

One option, of course, is to provide a custom comparator that has state, and selects between ascending and descending on each invocation of operator(), but I’m trying to avoid the performance overhead of having this branch for every comparison. The other alternative that I can see is to duplicate the entire algorithm, one for sorting ascending, and the other for descending.

Is there a better alternative to this problem?

EDIT: Since some people seem to be so eager to help without really understanding the problem here, I’ll try to elaborate a bit.

What I’ve implemented is an external sort algorithm (external merge sort). The algorithm uses a std::priority_queue during the merge phase. Now, the sort can either be ascending or descending. The std::priority_queue comparator must be different for those two cases. You might imagine that a simple sort algorithm could be easily parameterized to handle ascending/descending like such:

// psuedocode...
if (ascending) {
    if (a > b) // do something
} else {
    if (a < b) // do something
}

One problem with this is that the ascending flag has to be checked every iteration of the sort loop. ‘jalf’ suggests the compiler can “inline” this branch, but I don’t think I’ve seen it happen, at least not with VC++ (yes, I’ve looked at some assembly).

Now, when using a std::priority_queue to keep some things in sorted order, the actual type of the queue is different for ascending and descending sorts (since the comparator must be different, and it is a template parameter). So the options are:

  1. Duplicate the algorithm (function) for the descending case.
  2. Parameterize the algorithm on sort order and use one queue for ascending and a different one for descending.
  3. Use a comparator functor with a single piece of state (isAscending) so that operator()() can perform the right comparison for ascending and descending.
  4. Templatize the function and require the comparator be passed as a template argument.
  5. Use a function pointer as the comparator template argument.

Please note that I am not switching between two different queue behaviors during the algorithm (as some have asked). I am setting up the queue as a min or max queue at the start of the algorithm, and it remains as such for that particular sort.

Now to compare the options above.

Option 1 is out because of unwanted code duplication and maintenance (although it would likely produce the best performing code).

Option 2 is not desirable because of all the additional runtime checks and branching, and the unnecessary creation of a queue that will not be used.

Option 3 is more attractive because the branching is encapsulated/isolated in the comparator functor — but still requires a runtime check for each comparison (this is fundamentally what I wanted to avoid).

Option 4 pushes the problem up one level and requires the caller to know and have access to the comparator functors — kind of messy.

Option 5 seems pretty good — it makes for clean code by allowing the comparator function to differ at runtime without changing the type of the queue. The decision logic does not have to be exposed to the caller (as it would with option 4).

The only negative I can see with option 5 is that the compiler may not be able to inline the call through the function pointer — but in my case it did, because the called function was defined locally in the same translation unit. If it were not inlined, I’m guessing option 3 would have been better, but in my case performance was better with option 5.

Also, after I realized that option 5 was possible (I didn’t at first), it occurred to me that using function pointers instead of functors is probably not done much, and I suspect people sometimes jump through hoops to use functors (as I would have had to), when a function pointer may make for much cleaner code (particularly when performance isn’t a concern).

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-17T22:06:01+00:00Added an answer on May 17, 2026 at 10:06 pm

    Use templates

    template <typename Comparator>
    void algo()
    {
      std::priority_queue<int, std::vector<int>, Comparator> pqueue;
      ...
    }
    

    — edit
    I read your edit but I still don’t really get what’s bothering you. You say

    Option 4 pushes the problem up one level and requires the
    caller to know and have access to the comparator functors 
    -- kind of messy.
    

    Anyway the caller will have to choose between ascending or not.
    And, of course, it is not necessary for him to know which comparator type to use:

    void algo_ascending() {
      algo<Ascending_Comparator>();
    }
    void algo_descending() {
      algo<Descending_Comparator>();
    }
    

    Or even

    void algo(bool ascending) {
      if (ascending)
         algo<Ascending_Comparator>();
      else
         algo<Descending_Comparator>();
    }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have fairly large C++ library with several sub-libraries that support it, and I
I have a fairly large codebase that depends on MooTools v1.11 and am about
I have a fairly large PHP codebase (10k files) that I work with using
We have fairly large C++ application which is composed of about 60 projects in
I have fairly large script within an .svg file and I'd like to get
I have fairly large Latex document with a lot of TikZ figures inside. I
We have a fairly large SVN repository which we are looking to migrate to
I have a fairly large program written in C. It spans several files, and
I have a fairly large C++ solution in Visual Studio 2008 SP1. When I
I'm writing a little web utility that posts status updates to Twitter and/or Facebook.

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.