Initializing a multiset with a custom comparison function in C ++

Consider the following comparison function:

bool compare(std::shared_ptr<myObject> &lhs, std::shared_ptr<myObject> &rhs){ return lhs->value < rhs->value; } 

Now the idea is to initialize a multiset of type std::shared_ptr<myObject> , which arranges the elements with the above function. Therefore, from the book that I read, it should be done as follows:

 std::multiset<std::shared_ptr<myObject>, decltype(compare)*> myset{compare}; 

Question:

My question is that in the declaration I understand that the function pointer is passed to refer to the comparison function, but why do we initialize the wtih {compare} set ?? What is its significance and why should it be done like this?

+6
source share
4 answers

Since dialing requires a comparison functor to work. If you do not specify one, it will create a built one by default. In this case, since you are using a function pointer type, the default built one will be a null pointer that cannot be called; therefore, you should instead indicate the correct function pointer at runtime.

A better approach would be to use the type of the class of the function (the type of the functor aka); then the function call can be resolved at compile time, and the object built by default will do the right thing:

 struct compare { bool operator()(std::shared_ptr<myObject> &lhs, std::shared_ptr<myObject> &rhs) const { return lhs->value < rhs->value; } }; std::multiset<std::shared_ptr<myObject>, compare> myset; 
+7
source

The comparator passed to the template must be a type of what can be called using the function call operator. It will be either the class that overloaded this operator, or the type of the lambda pointer or function. In the cunstrutor set, an instance of this type must be passed. So decltype(compare)* is the type of the function pointer, and &compare is the function pointer.

+1
source

decltype(compare)* in the template parameter sets the type of comparator. It does not say which function should be used - is it compare , foo , bar or something else. Therefore, the constructor parameter.

+1
source

To access your elements, you need to provide a strict weak order function for your type.

std::multiset have the following constructor:

  explicit multiset (const key_compare& comp = key_compare(), const allocator_type& alloc = allocator_type()); 

As you can see, you can do this by passing a comp pointer to a function (or function object) to the constructor.


+1
source

Source: https://habr.com/ru/post/953559/


All Articles