Search code examples
c++multiset

What is the difference between "multiset<int, greater<int> > ms1" and "multiset<int> ms2(greater<int>())"


In my opinion, they are the same. But in Visual Studio 2015, they are definitely different.

//Ok, work properly
multiset<int, greater<int> > ms1;
ms1.insert(10);
ms1.insert(20);

//error, why?
multiset<int> ms2(greater<int>());
ms2.insert(30);
ms2.insert(40);

I don’t know why?


Solution

  • For your first example:

    multiset<int, greater<int> > ms1;
    

    This says that ms1 is a std::multiset, storing int, and using a comparison functor of the type std::greater<int>. You've left out constructor arguments, so the instance of the functor is a default constructed one, exactly as if you had passed std::greater<int>{}, like this:

    multiset<int, greater<int> > ms1(greater<int>{});
    

    In your second example:

    multiset<int> ms2(greater<int>());
    

    This one is a bit tricky. There are 2 problems here. The first one relates to what is called "The Most Vexing Parse". It has been answered many times, so I will simply link to one of those answers. Most vexing parse: why doesn't A a(()); work?

    So let's assume you understand that, and modify your code accordingly to this:

    multiset<int> ms2(greater<int>{});
    // or this
    multiset<int> ms2((greater<int>()));
    

    In this case, you've left out the type of the comparison functor, and gone with the default. The default is std::less<int>. So the above line is equivalent to this:

    multiset<int, std::less<int> > ms2(greater<int>{});
    

    What that says is that ms2 is a std::multiset, storing int, and using a comparison functor of type std::less<int>. You are then passing an instance of std::greater<int> to the constructor. std::less<int> and std::greater<int> are different types. You can't pass an instance of one to a function that is expecting an instance of the other.