This code works:
#include <iostream>
#include <queue>
#include <vector>
#include <functional>
using namespace std;
int main(){
priority_queue<int,vector<int>,greater<int> > pq;
pq.push(1);
cout<<pq.top()<<endl;
}
But,this code does not compile:
#include <iostream>
#include <queue>
#include <vector>
#include <functional>
using namespace std;
int main(){
priority_queue<int,vector<int>,greater<int>() > pq;
pq.push(1);
cout<<pq.top()<<endl;
}
Why?
All I understand is that greater<int>()
is a function object and priority_queue
accepts a binary predicate as third argument and that predicates are a special type of functors.
But how does the pair of braces make that difference.
In this declaration
priority_queue<int,vector<int>,greater<int> > pq;
the type template argument greater<int>
corresponds to the type of a structure.
In this declaration
priority_queue<int,vector<int>,greater<int>() > pq;
the type template argument greater<int>()
corresponds to the type of a function that has no parameters and has the return type greater<int>
The class template std::priority_queue
expects that the argument will be of a function object type that is a pointer to function or a class type that has a function operator.
To make it more clear compare for example these declarations
std::vector<int()> v1;
and
std::vector<int (*)()> v2;
For the first declaration the compiler will issue an error because the operator sizeof may not be applied to a function type int()
and the vector will be unable to allocate memory for its elements. Here int()
used as a type template argument is not an expression. It is a type-id.
In the second declaration the vector deal with pointers to function and it can allocate memory for its elements that are pointers.