Home > Net >  Proper declaration of C private standard library type member
Proper declaration of C private standard library type member

Time:03-16

I'm trying to declare a priority queue as a private member so all other methods in the class can access it.

However, I am not able to get this to work with a custom lambda compare function.

Moreover, what is the recommended way of handling such situations?

This works:

private:
    priority_queue<int, vector<int>, greater<int>> pq;

This does not work.

 private:
        static auto comp = [](int n1, int n2) {return (n1 > n2);};
        priority_queue<int, vector<int>, decltype(comp)> pq;

If I want to use an STL object with a custom compare function that is accessible by all class methods, how would I do so?

CodePudding user response:

The problem here is a fairly subtle one. Before C 20, lambdas are not default constructible, but from C 20 on, they are. So looking at this:

priority_queue<int, vector<int>, decltype(comp)> pq;

we can see that pq only knows the type of your comparator and will need to instantiate that type itself. But, before C 20, it cannot because the language doesn't support it.

So, there are two solutions to this, both equally easy:

  1. Add -std=c 20 to your compiler switches.

  2. Change that line of code to:

priority_queue<int, vector<int>, decltype(comp)> pq { comp };

And in fact for option 2, since you are (also) initialising comp inline, you also need:

static constexpr auto comp = [] (int n1, int n2) { return n1 > n2; };

or:

static inline auto comp = [] (int n1, int n2) { return n1 > n2; };

Both of which need C 17 or later.

Now you have passed as instance of comp to priority_queue's (alternative) constructor and so it has what it needs to get the job done.

The reason that std::greater works is that it's a just a normal functor that std::priority_queue can construct an instance of when it needs to.

I would also say that it's worth reading this.

And just to round off, the nice thing about using C 20 is that, for one-off cases, you can do things like this:

std::priority_queue<int, std::vector<int>, decltype ([] (int n1, int n2) { return n1 > n2; })> pq;

Which keeps it all neat and tidy.

  •  Tags:  
  • c
  • Related