为什么这两种情况的文档都说同样的事情,但它们以相反的方式声明,一个使用 greater<int>
而另一个使用 greater<int>()
。有人可以解释一下吗?
文档 priority_queue cpp library 说 comp
priority_queue<int, vector<int>, greater<int>> minheap; //works
priority_queue<int, vector<int>, greater<int>() > minheap; //why fail?
文档 cpp library sort 说了同样的事情,即 comp 可以是函数指针或函数对象。
sort (numbers.begin(), numbers.end(), std::greater<int>()); //works
sort (numbers.begin(), numbers.end(), std::greater<int>); //fail
最佳答案
在本声明中
priority_queue<int, vector<int>, greater<int>> minheap;
greater<int>
是一个模板参数,指定一个类型,对应priority_queue的类型模板参数class Compare
template<class T, class Container = vector<T>,
class Compare = less<typename Container::value_type>>
class priority_queue;
在这份声明中
sort (numbers.begin(), numbers.end(), std::greater<int>());
使用默认构造函数来创建
greater<int>
类型的临时对象。std::greater
是一个模板结构template<class T = void> struct greater;
那就是它的特化提供了一个类型。
您可以在声明中使用模板特化作为类型说明符。例如
std::greater<int> obj1;
std::greater<double> obj2;
std::greater<std::string> obj3;
在第一种情况下,您必须为相应的类型模板参数指定类型参数。
在第二种情况下,您必须指定一个
greater<int>
类型的对象。考虑到如果您尝试使用记录
std::greater<int>()
作为 priority_queue 的模板参数,那么编译器会将其视为具有返回类型 std::greater<int>
且没有参数的函数类型说明符。因为编译器需要一个类型说明符作为模板参数而不是表达式。但是将这样的函数类型指定为类型模板参数对于priority_queue 没有意义。为了更清楚地重写 std::sort 调用,请按以下方式
std::greater<int> obj;
sort (numbers.begin(), numbers.end(), obj );
正如你在这里看到的
std::greater<int>
是变量 obj
的类型说明符,它作为函数 std::sort
的参数提供。上面的调用和这个调用的区别sort (numbers.begin(), numbers.end(), std::greater<int>());
是在最后一种情况下,创建了一个
std::greater<int>
类型的临时对象,如 std::greater<int>()
。这是一个演示程序
#include <iostream>
#include <functional>
#include <iterator>
#include <algorithm>
int main()
{
int a[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
for ( const auto &item : a ) std::cout << item << ' ';
std::cout << '\n';
std::greater<int> comp;
// Here is used an already created object of the type std::greater<int>
std::sort( std::begin( a ), std::end( a ), comp );
for ( const auto &item : a ) std::cout << item << ' ';
std::cout << '\n';
// Here is used a remporary object of the type std::less<int>
std::sort( std::begin( a ), std::end( a ), std::less<int>() );
for ( const auto &item : a ) std::cout << item << ' ';
std::cout << '\n';
return 0;
}
程序输出是
0 1 2 3 4 5 6 7 8 9
9 8 7 6 5 4 3 2 1 0
0 1 2 3 4 5 6 7 8 9