【C++11っぽく】std::algorithm::find_if  を使う

#はじめに
C++は可読性も作業効率も(C言語に比べ)高くかけます
が、C言語の記述方法も可能なため、なかなかC++っぽく書けない人が多いです
C++でちゃんと書けば速度はほとんど落とす事なく、安全なコードがかけます

今回は、C++11ではじめて作業をして、とても快適になった
std::algorithm のさわりを。


#何が便利になったか
std::algorithmは、関数（オブジェクト）のコールバックをよく使いますが
C++11以前は、関数を作成し関数ポインタを渡すか、関数オブジェクトを作成する
必要があり、少し手間に感じていました
が、C++11では ラムダ関数が標準化され、関数オブジェクトが非常に簡単に作れます

ラムダ関数の登場により、std::algorithmは恩恵をかなり受け、使いやすくなりました

```cpp:rambda

// 関数ポインタ例
bool func(int &n){
  return(...);
}

auto fp = std::find( v.begin(), v.end(), (bool(*)(int))func );
...

// 関数オブジェクト例
struct OBJ{
  bool operator()(int n) const{
    return(...);
  }
};

auto fp = std::find_if( v.begin(), v.end(), OBJ() );
...


// ラムダ
auto fp = std::find_if( v.begin(), v.end(), [](int &n){ return(...); } );


```

このように、ラムダだと非常にすっきりしますね！
さらに、他の変数の値を保持させる場合は
関数ポインタでは難しいです
関数オブジェクトでは、引数付きコンストラクタを作成し値を保持しますが
ラムダでは、[]内部に変数名を書くだけで、値の保持（コピー、参照も選べる）が出来
非常に便利です


##find_if C言語で愚直に
find_ifは、検索の開始と終了を指定し
関数（オブジェクト）の条件がtrueだった最初のイテレータを返します

今回は HOGE構造体の flag==trueかつ、idの値が一致するものを取得します
まずは愚直に C言語での実装法


```cpp:C言語風
        struct HOGE{
            int         id;
            bool        flag;
        };

        //　C言語の書き方
        HOGE h[]={ {1,true},{2,true},{3,false} };
        for(int i=0; i<3; i++){
            if( (h[i].id== 1) && (h[i].flag==true)){
                std::cout << "for h" << std::endl;
            }
        }

```

愚直でCらしいですね！


## std::arrayでC言語風に愚直で
C++11では配列は std::arrayを使います。
生配列とちがい、サイズが取得出来たり、STLコンテナとして使えたり
生配列よりも安全かつ、オーバーヘッド無しで配列と同じように使えるので
今まで生配列を使っていた人はこの機会に stl::arrayに移行しましょう
（現在は 初期化時に配列数を明示的に指定する必要があるなど 多少面倒ですが、std::make_arrayが次に導入されるので　より便利になります）

```cpp:std#arrayC言語風
        struct HOGE{
            int         id;
            bool        flag;
        };

        // std::arrayを愚直にC言語で
        std::array<HOGE,3>  hh = {{ {1,true},{2,true},{3,false} }};
        for(int i=0; i<hh.size(); i++){
            if( (hh[i].id== 1) && (hh[i].flag==true)){
                std::cout << "for hh" << std::endl;
            }
        }
```

array<>::size() で配列の個数を取得出来る以外は、同じですね。
実際の動作もオーバーヘッドなく生配列と同じなので、速度も問題なく使えます

一つ不思議なのは、初期化時に　なぜか {}　が一つ多い事。
理由はわかりませんが、arrayを使う場合は、一つ多く囲わなければダメのようです


## for_each
C++で要素をなめる時は std::for_eachが使えます

```cpp:std#for_each
        struct HOGE{
            int         id;
            bool        flag;
        };

        std::array<HOGE,3>  hh = {{ {1,true},{2,true},{3,false} }};
        // std::for_each
        std::for_each(hh.begin(), hh.end(),
                      [](HOGE &h){
                          if((h.id==1)&&(h.flag==true)){
                              std::cout << "std::for_each hh" << std::endl;
                              break;
                          }
                      } );

```

for_eachの第一引数は、開始イテレータ、第二引数は終了イテレータ
第三引数に、実行する関数（オブジェクト）を指定します
少し STLっぽくなってきましたね


#range-based for-loop
std::for_each と似た動作をするものとして range-based for-loopがあります
日本語だと 範囲ベースforループ とか、よくわからない名前なので英語でいきます

std::for_eachに比べ、非常にすっきりした文法で全ての要素をなめます
std::for_eachだと 始めと終わりを指定出来るので、そういう用途の場合はそちらを使うべきですね

```cpp:std#range-based　for-loop
        struct HOGE{
            int         id;
            bool        flag;
        };

        std::array<HOGE,3>  hh = {{ {1,true},{2,true},{3,false} }};
        // range-based for-loop
        for( auto &a: hh){
            if( (a.id== 1) && (a.flag==true)){
                std::cout << "range-based for hh" << std::endl;
                break;
            }
        }
```

関数オブジェクトもなく、簡潔にかけます。
非常に便利なので 使ってみて下さい！


##std::find_if
やっと本命です
std::find_ifは、第一引数 開始イテレータ、第二引数 終了イテレータ
第三引数 条件 関数(オブジェクト)

となっております

```cpp:std#find_if
        struct HOGE{
            int         id;
            bool        flag;
        };

        std::array<HOGE,3>  hh = {{ {1,true},{2,true},{3,false} }};
        // std::find_if
        auto fi = std::find_if(hh.begin(), hh.end(),
                       [](HOGE &h){
                           return( (h.id==1)&&(h.flag==true));
                       } );

        if(fi != hh.end()){
            std::cout << "std::find_if" << std::endl;
        }
```

std::for_each に似た形ですが、第三引数には条件式を渡します
この条件式が trueの場合は find_ifをそこで停止し、trueになった時のイテレータが返却されます
どれにも一致しなかった場合は end() が返ります

おそらく、最もSTLの恩恵を授かったコードになっていると思います



##番外編 std::find
std::findは std::find_ifと違い、第三引数は条件関数オブジェクトではなく、値を指定します
例えば コンテナの中身が int等の場合は、数字を指定し一致したイテレータが取得できます
今回は 構造体なので、そのまま値を比較できないので
operator int() を実装し値の比較をします
（内部は-1というダミー値を使い　ダサいコードですが・・）


```cpp:std#find
        struct HOGE{
            int         id;
            bool        flag;

            operator int() {
                if(flag) {
                    return id;
                }else{
                    return -1;
                }
            };
        };

        std::array<HOGE,3>  hh = {{ {1,true},{2,true},{3,false} }};
        // std::find
        auto f = std::find(hh.begin(), hh.end(), 1);

        if(fi != hh.end()){
            std::cout << "std::find" << std::endl;
        }
```


あるいは、intにせず構造体で比較するには、operator==をオーバーライドし

```cpp:std#find
        struct HOGE{
            int         id;
            bool        flag;

            bool operator ==(const HOGE &h) {
                return( (h.flag==true)&&(this->id==h.id) );
            }
        };

        std::array<HOGE,3>  hh = {{ {1,true},{2,true},{3,false} }};
        // std::find
        auto f = std::find(hh.begin(), hh.end(), HOGE{1,true});

        if(f != hh.end()){
            std::cout << "std::find" << std::endl;
        }
```

実行速度とか多少オーバーヘッドありそうだけど、operator==をオーバーロードすると
すんなり書く事も出来ます

が

と複数条件のfindは  find_ifを使うのが良いと思います

ってことで、 std::find、std::find_if
今回はじめてSTLをマトモに仕事に使って　非常に便利だったので
オススメしておきます



また findは、setやmap、unordered_map等の場合はメンバ関数のものを使うと
二分木やハッシュを使い検索してくれるので
そちらを使って下さい！