関数アダプタ ネゲータ

http://www.geocities.jp/ky_webid/cpp/library/025.html

今回はネゲータについて勉強したいと思います。これも関数アダプタの一つです。

要は叙述関数の反対の結果得るための物です。

まず比較のためにネゲータを使わずに普通に叙述関数を使った処理を書いて見ます。

#include <iostream>
#include <functional>
#include <vector>
#include <algorithm>
using std::cout; using std::endl;

class COdd : public std::unary_function<int,bool> {
public:
    COdd(int num) {
        m_num = num;
    }
    bool operator()(int num) const {
        return num == m_num;
    }
private:
    int m_num;
};

int main () {
    std::vector<int> v;
    COdd eq(3);
    
    v.push_back(3);
    v.push_back(3);
    v.push_back(4);
    v.push_back(5);
    v.push_back(6);
    
    int num = std::count_if(v.begin(),v.end(), eq );
    
    cout << "3は" << num << "個ありました" << endl;
    
    return 0;
}
$ main
3は2個ありました

3と同じ値が何個あるかを判定する処理ですね。うまく動いています。

std::not1を使えばこの叙述関数eqの処理を反転することができます。つまり3じゃない値が何個あるかを判定できるということなのです。

#include <iostream>
#include <functional>
#include <vector>
#include <algorithm>
using std::cout; using std::endl;

class COdd : public std::unary_function<int,bool> {
public:
    COdd(int num) {
        m_num = num;
    }
    bool operator()(int num) const {
        return num == m_num;
    }
private:
    int m_num;
};

int main () {
    std::vector<int> v;
    COdd eq(3);
    
    v.push_back(3);
    v.push_back(3);
    v.push_back(4);
    v.push_back(5);
    v.push_back(6);
    
    int num = std::count_if(v.begin(),v.end(), std::not1( eq ) );
    
    cout << "3以外は" << num << "個ありました" << endl;
    
    return 0;
}
$ main
3以外は3個ありました

このようにstd::not1( eq )のようにして渡すと、3以外という判定になります。

またstd::not2というのもありますがそちらは引数が二つの時の関数なのでbinary_function経由の場合に使用します。