Initializing multiset with custom comparison function in C++

て烟熏妆下的殇ゞ 提交于 2019-12-03 09:40:37

问题


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 understad a function pointer is passed to refer to compare function, but why are we initiazling the set wtih {compare}?? what is its importance and why is it necessary to do so like this??


回答1:


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;



回答2:


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.





回答3:


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.




回答4:


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.



来源:https://stackoverflow.com/questions/18718379/initializing-multiset-with-custom-comparison-function-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!