Search code examples
c++c++11templatespredicatefunctor

Difference between std::greater<int>() and std::greater<int>?


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.


Solution

  • 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.