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

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

在我看来,它们是一样的。但是在Visual Studio2015年,他们肯定不一样了。

//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);

不知道为什么?

第一个例子:

multiset<int, greater<int> > ms1;

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

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

在你的第二个例子中:

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

这个有点棘手。这里有两个问题。第一个与所谓的"The Most Vexing Parse"有关。它已被多次回答,所以我将简单地 link 回答其中一个答案。 Most vexing parse: why doesn't A a(()); work?

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

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

在本例中,您省略了比较仿函数的类型,并使用了默认值。默认值为 std::less<int>。所以上面一行等同于:

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

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