Вопрос

Consider following comparison function:

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

Now idea is to initialize a multiset of type std::shared_ptr<myObject> which orders elements with above function. So from book i read it should be done like this:

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

QUESTION:

My question is, in the declaration i understand a function pointer is passed to refer to compare function, but why are we initializing the set with {compare}? What is its importance and why is it necessary to do so like this??

Это было полезно?

Решение

Because the set needs a comparison functor to work with. If you don't specify one, it will make a default-constructed one. In this case, since you're using a function-pointer type, the default-constructed one will be a null pointer, which can't be called; so instead, you have to provide the correct function pointer at run time.

A better approach might be to use a function class type (a.k.a. functor type); then the function call can be resolved at compile time, and a default-constructed object 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;

Другие советы

In order to access your elements, you need to provide function for strict weak ordering 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 comp function pointer (or function object) to the constructor.


decltype(compare)* in the template parameter specifies the type of the comparator. It doesn't tell which function is to be used - whether is it compare, foo, bar or something else. Hence the constructor parameter.

The comparator passed to the template has to be the type of something that can be called with the function call operator. That would be either a class that has overloaded that operator, or the type of a lambda or a function pointer. In the cunstrutor of set, an instance of that type has to be passed. So decltype(compare)* is the function pointer type, and &compare is the function pointer.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top