-1

This is all in one class. Class B holds a list.

class A{
   bool compare = [](const B& lhs, const B& rhs){
     return lhs.list.size() >= rhs.list.size();
   };

   priority_queue<B, vector<B>, decltype(compare)> pq(compare);
};

I get any error on pq. I'm very unfamiliar with the lambda function so I have no clue how to solve this function.

ERROR: compare is not a type

  • 1
    Off-topic: Why not just a regular, run of the mill, static member function? There's no *need* to use a lambda here. – StoryTeller - Unslander Monica Apr 18 '18 at 07:50
  • @StoryTeller This compare function will have multiple return values. So I will use a switch statement to access a member in class A which will decide what return value compare will return. Edit: unless you know of a way for a comparator to have multiple returns. – Plays4u Apr 18 '18 at 07:51
  • This lambda (assuming it was "fixed") isn't going to help you do that either... – StoryTeller - Unslander Monica Apr 18 '18 at 07:53
  • @Plays4u Then you need to access the `A` instance inside the function, so you need a member-function and/or a capturing-lambda. – Holt Apr 18 '18 at 08:05
  • 1
    In my opinion, it makes sense to use a lambda here, if you need to replace the functional it represents. @StoryTeller: A lambda that is "fixed" is useless, isn't it? Lamdbas are there to change between implementations of an aspect. – user3640029 Apr 18 '18 at 08:06
  • @user3640029 no, a lambda is *exactly* an unnamed class with an `operator()` – Caleth Apr 18 '18 at 08:47

2 Answers2

2

The member compare is a bool, not a function, it has the value true. There is an implicit conversion from your lambda type to bool(*)(const B&, const B&), and then a conversion to bool from the function pointer type. If you were to add anything to the capture list, that line would fail, as stateful lambdas don't convert to function pointers.

You can't declare the data member auto, so if you want it to be a lambda, it can't be at class scope. But you don't need it to be, a static function works fine.

class A{
   static bool compare(const B& lhs, const B& rhs) {
     return lhs.list.size() >= rhs.list.size();
   }; 

   std::priority_queue<B, std::vector<B>, decltype(compare)> pq;
public:
   A():pq(compare){}
};
Caleth
  • 52,200
  • 2
  • 44
  • 75
-2

Several things needed to be changed. First, the lambda declaration is strange. Lambdas give their return value at the end (I think it is allowed though, but in my opinion might be read as trying to assign a lambda to a bool variable.

Second, I was unable to do the same with auto or similar keywords capturing the actual type of the lambda as this would imply static constexpr quite far from what you have.

Therefore, I explicitly gave a good type to the lambda (note that types of lambdas are always strange, so it is in many situations better to assign a lambda to a std::function<> if you want readable error messages and it is almost never a problem. If you don't know the signature, you will most likely have to template it. But then, the class with the lambda will be templated, too and there is no problem.

Finally, the initialization of the queue with the element was ill-formed, because it might be difficult to construct all the objects in the right order. Therefore, the initialization has been moved to the constructor of A.

Here is my correction:

#include<queue>
#include<list>
#include<vector>
#include<functional>

using namespace std;

struct B{
  std::list<int> list;
};

class A{
   function<bool(const B&, const B&)> compare = [](const B& lhs, const B& rhs) ->bool{
     return lhs.list.size() >= rhs.list.size();
   }; 

   std::priority_queue<B, vector<B>, decltype(compare)> pq;
   A():pq(compare){}
};


int main()
{
}

Finally, note that I don't like the member of B to be named list, as list is also the type.

user3640029
  • 165
  • 4