Why the documentation for both cases says the same thing, but they are declared in an opposite way, one uses greater<int>
while the other uses greater<int>()
. Could anyone please shed some light on it?
The documentation priority_queue cpp library says that comp
can be Comparison object to be used to order the heap. This may be a function pointer or function object
priority_queue<int, vector<int>, greater<int>> minheap; //works
priority_queue<int, vector<int>, greater<int>() > minheap; //why fail?
The documentation cpp library sort says the same thing, that is, comp can either be a function pointer or a function object.
sort (numbers.begin(), numbers.end(), std::greater<int>()); //works
sort (numbers.begin(), numbers.end(), std::greater<int>); //fail
In this declaration
priority_queue<int, vector<int>, greater<int>> minheap;
greater<int>
is a template argument that specifiers a type and corresponds to the type template parameter class Compare
of the priority_queue
template<class T, class Container = vector<T>,
class Compare = less<typename Container::value_type>>
class priority_queue;
In this statement
sort (numbers.begin(), numbers.end(), std::greater<int>());
there is used the default constructor to create a temporary object of the type greater<int>
.
std::greater
is a template structure
template<class T = void> struct greater;
that is its specialization provides a type.
You can use the template specializations as type specifiers in declarations. For example
std::greater<int> obj1;
std::greater<double> obj2;
std::greater<std::string> obj3;
In the first case you have to specify the type argument for the corresponding type template parameter.
In the second case you have to specify an object of the type greater<int>
.
Take into account that if you will try to use the record std::greater<int>()
as a template argument for the priority_queue then the compiler considers it as a function type specifier that has return type std::greater<int>
and has no parameters. Because the compiler expects a type specifier as a template argument and not an expression. But specifying such a function type as a type template argument does not make sense for the priority_queue.
To make it more clear rewrite a call of std::sort the following way
std::greater<int> obj;
sort (numbers.begin(), numbers.end(), obj );
As you see here is std::greater<int>
is a type specifier for the variable obj
which is supplied as an argument to the function std::sort
. The difference between the call above and this call
sort (numbers.begin(), numbers.end(), std::greater<int>());
is that in the last case there is created a temporary object of the type std::greater<int>
like std::greater<int>()
.
Here is a demonstrative program
#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;
}
The program output is
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
The third template argument for std::priority_queue
is the type of the comparator.
With greater<int>()
you create an instance (an object) of the greater<int>
class, and you pass this instance (object) as argument instead of the type greater<int>
.
For std::sort
the third function argument is an actual object (or rather, anything that is callable).
Regarding the reference you link to, it's a reference of the constructor, not the std::priority_queue
template itself. Constructor arguments are like function arguments, and are very different from the template arguments.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With