predicateの記述法
c++の理解が浅すぎるので迂闊なことは書けないですが自分へのメモ。
std::sortやstd::transformを使っているとpredicateを指定する状況が自然に生まれてきます。
predicateは関数オブジェクトで表すことができます。関数オブジェクトは()をオーバーロードしたクラスで表すことができます。途中で関数ポインタとの違いが分からなくなって
[*1]を参考にしました。インライン化に関しての理解が浅いので後で[*2]を読みます。
ところでlambda式が評価されるとclosure objectになります[*3]。closure objectは一種の関数オブジェクトになります。よってpredicateはlabmda式で表すことができます。
サンプルコード
int main() { auto compare = [](const std::complex<float> &a, const std::complex<float> &b) -> bool { if(abs(a) == abs(b)) { if(a.real() == b.real()) return a.imag() > b.imag(); return a.real() > b.real(); } else { return abs(a) > abs(b); } }; std::vector<std::complex<float>> seq; seq.push_back(std::complex<float>(0.5f, 1.0f)); seq.push_back(std::complex<float>(0.5f, 0.3f)); seq.push_back(std::complex<float>(4.2f, -1.0f)); seq.push_back(std::complex<float>(0.0f, -2.0f)); seq.push_back(std::complex<float>(2.0f, 0.0f)); seq.push_back(std::complex<float>(-2.0f, 0.0f)); std::priority_queue<std::complex<float>, std::vector<std::complex<float>>, decltype(compare)> queue(compare); for(auto element : seq) { queue.push(element); } std::sort(seq.begin(), seq.end(), compare); std::cout << "std::sort" << endl; for(auto element : seq) { std::cout << element.real() << ',' << element.imag() << std::endl; } std::cout << "std::priority_queue" << endl; for(; !queue.empty(); queue.pop()) { auto element = queue.top(); std::cout << element.real() << ',' << element.imag() << std::endl; } }
出力
std::sort 4.2,-1 2,0 0,-2 -2,0 0.5,1 0.5,0.3 std::priority_queue 0.5,0.3 0.5,1 -2,0 0,-2 2,0 4.2,-1