C++0xのLambda式による量化関数

Lambda式の勉強をちょっとしたので、衝動的に量化関数を実装してみた。

#include <iostream>
#include <vector>
using namespace std;
#define vi vector<int>
#define vit vector<int>::iterator
#define all(a) begin(a),end(a)

template <class T, class LAMBDA>
bool forall(T b, T e, LAMBDA l) {
    int faf = 1;
    for (T it = b; it != e; it++) {
        if (!l(it)) {
            faf = 0;
            break;
        }
    }
    return faf;
}
template <class T, class LAMBDA>
bool thereexists(T b, T e, LAMBDA l)
{
    return !forall(b, e, [l](T it) {return !l(it);});
}

main()
{
    vi a = {3, 6, 9, 12};

    // for all it in a there exists j in [4, 5], *it can divided by j -> 0
    cout <<
        forall(all(a), [](vit it) {
            return thereexists(4, 5, [&](int j) {
                return !(*it % j);
            });
        })
    << endl;

    cout << forall(2, 3, [&](int it) {return it > 2;}) << endl; // 0
    cout << forall(3, 4, [&](int it) {return it > 2;}) << endl; // 1
    cout << forall(all(a), [&](decltype(begin(a)) it) {return !(*it % 2);}) << endl; // 0
    cout << forall(all(a), [&](decltype(begin(a)) it) {return !(*it % 3);}) << endl; // 1
    cout << thereexists(all(a), [&](decltype(begin(a)) it) {return !(*it % 5);}) << endl; // 0
    cout << thereexists(all(a), [&](decltype(begin(a)) it) {return !(*it % 12);}) << endl; // 1
}

どれくらい意味がわかりやすくなるかというと、こんな感じ。量化記号をそのまま実装できる点で、書きやすく意味が一目瞭然。
before

        int flag = 0;
        for (auto itj = candidacy.begin(); itj != candidacy.end(); itj++) {
            if (iti == itj)
                continue;
            int faf = 1;
            for (int h = 0; h < COLOR_NUM; h++) {
                if (!((*iti)[h] >= (*itj)[h])) {
                    faf = 0;
                    break;
                }
            }
            if (!((*iti)[8] >= (*itj)[8]))
                faf = 0;
            if (!faf) {
                continue;
            } else if (faf) {
                flag = 1;
                break;
            }
        }
        if (flag)
            iti = candidacy.erase(iti, iti + 1);
        else
            iti++;

after

        if (there_exists(all(candidacy), [&](itr(candidacy) itj) { return iti != itj && (*iti)[8] >= (*itj)[8] && for_all(0, (int)COLOR_NUM, [&](int h){ return (*iti)[h] >= (*itj)[h]; });}))
            iti = candidacy.erase(iti, iti + 1);
        else
            iti++;

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>