読者です 読者をやめる 読者になる 読者になる

趣味プログラマによるOSS開発日誌

趣味で作っているOSSソフトウェアの紹介や関連技術の紹介、楽曲製作、Webデザイン勉強状況を紹介します。

C++11 ラムダ関数を利用してみる

C++STLを使うときに毎回iteratorで回していた部分があって、毎回面倒であった。
そこで今更であるが、C++11で採択されたラムダ関数の使い方/使い道を調べ、少しだけ分かった気がするのでまとめておく。


【ラムダ関数を使う理由】
std::sortやstd::for_each等の最後の引数に関数オブジェクトを渡すために、これらの関数の直前に関数オブジェクトを書くことが多かった。
しかしこれらの呼び出しの前に、struct{... void operator() ...}のように毎回関数オブジェクトを定義するのは面倒であるし、コードの記述量が増えてソースコードの処理の流れが分かりづらくなる。
ラムダ関数を利用することで、これらの問題を解消することが出来る。
※std::sortやstd::for_eachの第3引数に関数ポインタを使うべきではない理由については、以下または、Effective STLの「第46項 アルゴリズムのパラメータとして関数の代わりに関数オブジェクトの使用を考えよう」を参照のこと。
http://d.hatena.ne.jp/mickey24/touch/searchdiary?word=*%5BC%2B%2B%5D


【使い方】
実際のラムダ関数の使い方を以下に示す。

1. 基本形
※基本形という表現が正しいのかについては置いておく。

std::list < int > l;

l.push_back( 3 );
l.push_back( 5 );

std::for_each( l.begin(), l.end(), []( int v ){ std::cout << v << std::endl; } );

[プログラムの実行結果]

3
5

std::listに保存されている値が全て表示される。

2. ラムダ関数内部で特定の変数を利用したい時

std::list < int > l;
int n = 10;

l.push_back( 3 );
l.push_back( 5 );

std::for_each( l.begin(), l.end(), [n]( int v ){ std::cout << n << std::endl; } );

[プログラムの実行結果]

10
10

変数nの値がstd::listの要素数分だけ出力される。

3. ラムダ関数内部でクラスのメンバ変数利用したい時

class Hoge
{
    int m_Foo;
public:
    void Piyo();
};

void Hoge::Piyo()
{
    std::list < int > l;

    m_Foo = 100;;

    l.push_back( 3 );
    l.push_back( 5 );

    std::for_each( l.begin(), l.end(), [this]( int v ){ std::cout << m_Foo << std::endl; } );
}


int main()
{
    Hoge h;

    h.Piyo();

    return 0;
}

[プログラムの実行結果]

100
100

メンバ変数m_Fooの値がstd::listの要素数分だけ出力される。


他にもラムダ関数に関してはいろいろあるようだが、現在使っているのは上記3つのパターン。
まだ使いこなしていないが、ラムダ関数のおかげでソースコードが非常に簡潔になった。
今後、他の場合について利用することがあれば、追加していきたいと思う。


[参考文献]