“multiset<int, Greater<int> > ms1”和“multiset<int> ms2(greater<int>())”有什么区别

Tan*_*iao 0 c++ multiset

在我看来,它们是一样的。但在 Visual Studio 2015 中,它们绝对不同。

//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);
Run Code Online (Sandbox Code Playgroud)

我不知道为什么?

Ben*_*ley 5

对于您的第一个示例:

multiset<int, greater<int> > ms1;
Run Code Online (Sandbox Code Playgroud)

这表示这ms1是一个std::multiset,存储int和使用类型的比较函子std::greater<int>。你已经省略了构造函数参数,所以函子的实例是一个默认构造的实例std::greater<int>{},就像你传递了一样,就像这样:

multiset<int, greater<int> > ms1(greater<int>{});
Run Code Online (Sandbox Code Playgroud)

在你的第二个例子中:

multiset<int> ms2(greater<int>());
Run Code Online (Sandbox Code Playgroud)

这个有点棘手。这里有2个问题。第一个与所谓的“最令人烦恼的解析”有关。它已被多次回答,所以我将简单地链接到其中一个答案。最令人头疼的解析:为什么没有 A a(()); 工作?

因此,让我们假设您理解这一点,并相应地修改您的代码:

multiset<int> ms2(greater<int>{});
// or this
multiset<int> ms2((greater<int>()));
Run Code Online (Sandbox Code Playgroud)

在这种情况下,您忽略了比较函子的类型,而使用了默认值。默认值为std::less<int>. 所以上面这行相当于:

multiset<int, std::less<int> > ms2(greater<int>{});
Run Code Online (Sandbox Code Playgroud)

也就是说,这ms2是一个std::multiset,存储int和使用类型的比较函子std::less<int>。然后将 的实例传递std::greater<int>给构造函数。std::less<int>并且std::greater<int>是不同的类型。您不能将一个的实例传递给需要另一个实例的函数。