C++11,14のラムダ関数について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
新米

C++11,14のラムダ関数について

#1

投稿記事 by 新米 » 7年前

C++11,14のラムダ関数について質問させていただきます。

Q1: どんな場合ラムダ関数を使うと便利になりますか。

Q2: ラムダ関数のパフォーマンスはどうですか。
    例えば、inline関数と同じでしょうか。

Q3: ラムダ関数により不都合を引き起こす場合やラムダ関数のデメリットも合わせて教えていただければ、助かります。

どうぞ宜しくお願い致します。

Rittai_3D
記事: 525
登録日時: 11年前

Re: C++11,14のラムダ関数について

#2

投稿記事 by Rittai_3D » 7年前

当方C++初心者レベルなので間違えていることを言っていたら申し訳ないです。
Q1: どんな場合ラムダ関数を使うと便利になりますか。
このようなコードを書いてみると便利さがわかるかと思います。

コード:

#include <iostream>
#include <algorithm>
#include <utility>
#include <vector>
using namespace std;

struct show
{
    void operator()( int& v )
    {
        cout << v << endl;
    }
};

int main()
{
    vector< int > vec { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, };
    for_each( begin( vec ), end( vec ), show() );
}

コード:

#include <iostream>
#include <algorithm>
#include <utility>
#include <vector>
using namespace std;

int main()
{
    vector< int > vec { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, };
    for_each( begin( vec ), end( vec ), []( int& v ) { cout << v << endl; }  );
}
Q2: ラムダ関数のパフォーマンスはどうですか。
    例えば、inline関数と同じでしょうか。
パフォーマンスは全く考えたことがありませんでしたので、検索してみました。
http://d.hatena.ne.jp/niwagata/20120319/1332162653 こちらが参考になるかと思います。
もしくは実測してみることをお勧めします。
Q3: ラムダ関数により不都合を引き起こす場合やラムダ関数のデメリットも合わせて教えていただければ、助かります。
不都合・デメリットは特にないと思います。
オフトピック
不都合・デメリットを強いてあげるなら、変数のキャプチャーの指定をし忘れることくらいでしょうか。
これを不都合に入れてよいのかは不明ですが・・・。
初心者です

新米

Re: C++11,14のラムダ関数について

#3

投稿記事 by 新米 » 7年前

お返答ありがとうございます
ただ、書かれた例文の中に下記の文の中にvecは定義済みで、 vは分かりません。
for_each( begin( vec ), end( vec ), []( int& v ) { cout << v << endl; } );
もう一度ご説明お願いできますか。

教えていただいた実行速度に関するリンクはとても素晴らしいすね。
速度からすれば、ラムダ関数はinlineに近いですね――――原理的にまったく同じかも知れません。

またどうぞ宜しくお願い致します。

Rittai_3D
記事: 525
登録日時: 11年前

Re: C++11,14のラムダ関数について

#4

投稿記事 by Rittai_3D » 7年前

新米 さんが書きました:ただ、書かれた例文の中に下記の文の中にvecは定義済みで、 vは分かりません。
for_each( begin( vec ), end( vec ), []( int& v ) { cout << v << endl; } );
もう一度ご説明お願いできますか。
vは普通の関数でも使う仮引数です。

コード:

#include <iostream>
#include <algorithm>
#include <utility>
#include <vector>
using namespace std;
 
void output( int& v )
{
    cout << v << endl;
}

int main()
{
    vector< int > vec { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, };
    for_each( begin( vec ), end( vec ), output );
}
こうすればわかりますか?

std::for_each()のリファレンスを見るとわかると思います。
内部を見てみると

コード:

template< class InputIterator, class UnaryFunction >
UnaryFunction for_each( InputIterator first, InputIterator last, UnaryFunction function )
{
    for( ; first != last ; ++first ) {
        function( *first );
    }
    
    return std::move( function );
}
のようになっていて、[ first, last ) 内のiteratorに対して function の処理を行うようになっています。
上の例の場合、output()は引数を出力する関数なので、「[ first, last ) 内のiteratorに対して、引数を出力する関数を呼び出す」ということです。
ラムダ式を渡すにしても同じですが、関数をあらかじめ作っておく必要がないです。
その場で関数を作っていると思えば理解しやすいかと思います。
オフトピック
解説が非常に苦手なので混乱させてしまったら申し訳ないです・・・。
初心者です

新米

Re: C++11,14のラムダ関数について

#5

投稿記事 by 新米 » 7年前

丁寧なご解説有難う御座います。
お陰様でLambda関数自体が分かりましたが、
正直その存在価値に関してはよくわかりません。

(1 )  Lambda関数のコード量が多い場合、
ある関数の途中にいきなりLambda関数のコードが挿入されたら、アルゴの流が悪くなりますね。

(2 )  Lambda関数のコードが少なければ、直にそのコードを現在処理の中に入れればOKで、
わざわざ特殊な形式を使って導入される必要がないではと思いますが。

要はどのケースで、Lambda関数を使う利点が見えません。

自分の理解力不足で申しわけありませんが、何かヒントでもいただければ幸いです。

Rittai_3D
記事: 525
登録日時: 11年前

Re: C++11,14のラムダ関数について

#6

投稿記事 by Rittai_3D » 7年前

新米 さんが書きました:(1 )  Lambda関数のコード量が多い場合、
ある関数の途中にいきなりLambda関数のコードが挿入されたら、アルゴの流が悪くなりますね。
>アルゴの流
が何なのかわからないですが、この場合、個別に関数を用意すればよいのではないでしょうか。
ラムダ式は
「ラムダ式(lambda expressions)」は、簡易的な関数オブジェクトをその場で定義するための機能である。
http://cpprefjp.github.io/lang/cpp11/la ... sions.html
とある通り、その場で関数を用意します。コード量が長いものはラムダ式にするべきではないと思います。
新米 さんが書きました:(2 )  Lambda関数のコードが少なければ、直にそのコードを現在処理の中に入れればOKで、
わざわざ特殊な形式を使って導入される必要がないではと思いますが。
引数に関数をとる場合はどうすればよいのでしょうか。直に処理をかけないと思いますが・・・。
特にSTLを使う場合、どうすればよいのか教えていただきたいです。
初心者です

アバター
tk-xleader
記事: 158
登録日時: 13年前
連絡を取る:

Re: C++11,14のラムダ関数について

#7

投稿記事 by tk-xleader » 7年前

ラムダ式の存在意義ですか…

これはSTLをよく使う人じゃないと分かりづらいと思いますし、C++の場合ラムダ式を使わずとも不利益はありません(ゼロ・オーバーヘッドの原則)から、存在意義が分かるまで別に使用しなくてもいいのではないかと思います。

STLで自作ファンクタをよく使う人ならラムダ式がかなり便利であることが実感できると思いますが…

新米

Re: C++11,14のラムダ関数について

#8

投稿記事 by 新米 » 7年前

完全に分かるは言えませんが、ずいぶんすっきりしたような感じです。
これからさらに勉強しなければならないと思います。

確かに面白いです。

皆さん親切なご教授ありがとうございました。

閉鎖

“C言語何でも質問掲示板” へ戻る