Вопрос

I am really having a hard time understanding these declaration

        static bool compare ( const shared_ptr<int> lhs,const shared_ptr<int> rhs )
                    { return (*lhs) < (*rhs) ; }
        multiset<shared_ptr<int>,decltype(compare)*> item{ compare } ;

if I dont give pointer after decltype(compare) it gives error? Why error? why should I supply bool* not bool as predicate like algorithm functions, again whats the benifit of giving compare in curly braces in item { compare } ? will it insert objects in multiset in sorted order? if I didnt give the { compare } what would happen?

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

Решение

The type expected by multiset second parameter is a Predicate. That is the type of an object c such that c(lhs, rhs) returns something convertible to bool.

The type of compare and decltype(compare) is bool(shared_ptr<int>, shared_ptr<int>), a function type. There can't be values of function type, but there can be values of pointers and references to function types. That's why you need the * there. (Actually, there are values of function types and are those things that you declare as functions, but those cannot be created, copied, nor pretty much anything besides calling them and getting their address.) Summing up:

decltype(compare)* ==> bool (*)(shared_ptr<int>, shared_ptr<int>)

which is a pointer to a function taking two shared_ptr<int>s by value and returning a bool. Then, in the multiset constructor, you give it a value of that type:

items{ compare }; // value 

or more specifically, a value of a function type that will decay to a function pointer type. So let's make that explicit:

items{ &compare }; // pointer to function compare

If you didn't give it anything, then it would be a null pointer, and when trying to call it to do the comparison your application would crash.

In summary, you chose a hell of a complicated case to go through (and I have skipped a few things I should mention). This is a simpler approach:

struct shared_ptr_compare
{
    bool operator()(std::shared_ptr<int> const& lhs, std::shared_ptr<int> const& rhs) const
    { return /*...*/; }
};

multiset<shared_ptr<int>, shared_ptr_compare> item; // no need to initialize 
      // shared_ptr_compare with anything, a default value will do just fine

Note: I dropped the top-level const modifier as it has no effect on a function parameter, it only signals the function body that the values cannot be changed. So it does have meaning, but complicates explaining types.

Note 2: You should take those parameters as shared_ptr<int> const& (same thing as const shared_ptr<int>&), since you do not actually need a copy and those copies have to keep a reference counter which is an operation that has to be synchronized among threads.

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