Mano
Mano

Reputation: 163

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.

Upvotes: 13

Views: 15123

Answers (2)

Vlad from Moscow
Vlad from Moscow

Reputation: 311010

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.

Upvotes: 11

Edgar Rokjān
Edgar Rokjān

Reputation: 17483

From cppreference:

template<
     class T,
     class Container = std::vector<T>,
     class Compare = std::less<typename Container::value_type>
 > class priority_queue;

Compare - A Compare type providing a strict weak ordering.

So for std::priority_queue you pass a type of comparator as a template parameter.

On the other hand,

greater<int>()

stands for creation of new object of type greater<int> which is not an option in your case.

Upvotes: 3

Related Questions