プログラム系統備忘録ブログ

記事中のコードは自己責任の下でご自由にどうぞ。

C++でpriority_queueの比較関数にラムダ式を指定する方法

2017/01/29(日) 追記
std::priority_queue - cppreference.com にあるように、テンプレート引数にCompareはC++03以前にもあり、
std::priority_queue::priority_queue - cppreference.com にあるようにComparerをコンストラクタ引数に渡せます。

priority_queueのコンストラクタでCompareを渡さなかった場合はfunctionがデフォルト構築されます。
std::function::function - cppreference.com にあるようにデフォルト構築されたfunctionはemptyとなり、
std::function - cppreference.com にあるようにemptyなfunctionを呼び出すとstd::bad_function_callがthrowされます。
(追記ここまで)
実験環境はVisualStudio2012とg++.exe (tdm-1) 4.6.1。

テンプレート引数の叙述関数部分にラムダ式を投げる方法の話(今回はpriority_queue)。
仕様書などを読んだわけではありませんが、実験したら出来たのでメモ。

以下のソースのように、叙述関数を要求される第三テンプレート引数にfunctionを渡すのがミソ。
そしてコンストラクタでラムダ式を渡します。

#include<stdio.h>
#include<queue>
#include<vector>
#include<functional>

int main(){
    using namespace std;

    priority_queue<int, vector<int>, function<bool(int,int)>>q(
        [](int a,int b){return a>b;}
    );
    q.push(3);
    q.push(1);
    q.push(5);
    while(!q.empty()){
        printf("%d\n", q.top());
        q.pop();
    }
    return 0;
}

出力結果は以下になります。

1
3
5

コンストラクタに引数を渡すのを忘れていると、コンパイルエラーは発生しませんが実行時エラーが発生するので注意が必要です。

priority_queue<int, vector<int>, function<bool(int,int)>>q;
q.push(3);
q.push(1);  // 実行時に例外発生