web-dev-qa-db-ja.com

std :: greater <int>()とstd :: greater <int>の違いは?

このコードは機能します:

_#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;
}
_

ただし、このコードはコンパイルされません。

_#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;
}
_

どうして?
私が理解しているのは、greater<int>()は関数オブジェクトであり、_priority_queue_は3番目の引数としてバイナリ述語を受け入れ、述語は特殊なタイプのファンクターであることです。しかし、中括弧のペアはどのようにその違いを生むのでしょうか。

8
Manohar

この宣言では

_priority_queue<int,vector<int>,greater<int> > pq;
_

タイプテンプレート引数_greater<int>_は、構造体のタイプに対応します。

この宣言では

_priority_queue<int,vector<int>,greater<int>() > pq;
_

型テンプレートの引数greater<int>()は、パラメーターを持たず、戻り値の型_greater<int>_を持つ関数の型に対応します。

クラステンプレート_std::priority_queue_は、引数が関数へのポインタである関数オブジェクト型または関数演算子を持つクラス型であることを想定しています。

より明確にするために、たとえばこれらの宣言を比較してください

_std::vector<int()> v1;
_

そして

_std::vector<int (*)()> v2;
_

最初の宣言では、演算子sizeofが関数型int()に適用されない可能性があり、ベクトルがその要素にメモリを割り当てることができないため、コンパイラはエラーを発行します。ここで、型テンプレート引数として使用されるint()は式ではありません。タイプIDです。

2番目の宣言では、ベクトルは関数へのポインターを処理し、ポインターである要素にメモリを割り当てることができます。

7

から cppreference

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

比較-比較typeは、厳密な弱順序を提供します。

したがって、std :: priority_queueの場合、テンプレートパラメータとしてコンパレータのタイプを渡します。

一方、

greater<int>()

タイプgreater<int>の新しいオブジェクトの作成を表しますが、これはオプションではありません。

3
Edgar Rokjān