[解決済み】C++11のラムダ式って何?
質問
C++11のラムダ式とは何ですか?どんな時に使うのでしょうか?ラムダ式は、導入前には不可能だったどのような問題を解決するのでしょうか?
いくつかの例とユースケースがあると便利です。
解決方法は?
問題点
C++には、以下のような便利な汎用関数があります。
std::for_each
と
std::transform
これは非常に便利なものです。残念ながら、これらは非常に使いにくいものでもあります。
ファンクタ
を適用したい場合、その関数に固有のものである。
#include <algorithm>
#include <vector>
namespace {
struct f {
void operator()(int) {
// do something
}
};
}
void func(std::vector<int>& v) {
f f;
std::for_each(v.begin(), v.end(), f);
}
のみを使用する場合
f
一度だけ、しかも特定の場所で、些細で一回限りのことをするためにクラス全体を書くのはやりすぎだと思われます。
C++03では、ファンクタをローカルに保つために、以下のように書きたくなるかもしれません。
void func2(std::vector<int>& v) {
struct {
void operator()(int) {
// do something
}
} f;
std::for_each(v.begin(), v.end(), f);
}
が、これは許されない。
f
に渡すことはできません。
テンプレート
関数を使用することができます。
新しい解決策
C++11 ではラムダが導入され、インラインの匿名ファンクタを書くことで
struct f
. 小さな単純な例では、この方が読みやすく(すべてを一箇所にまとめておける)、保守も簡単になる可能性があります。
void func3(std::vector<int>& v) {
std::for_each(v.begin(), v.end(), [](int) { /* do something here*/ });
}
ラムダ関数は、匿名ファンクタのための単なる構文上の糖分です。
戻り値の型
単純なケースでは、ラムダの戻り値の型が推論されます、例えば。
void func4(std::vector<double>& v) {
std::transform(v.begin(), v.end(), v.begin(),
[](double d) { return d < 0.00001 ? 0 : d; }
);
}
しかし、より複雑なラムダを書き始めると、例えばコンパイラが戻り値の型を推論できないケースにすぐに遭遇することになります。
void func4(std::vector<double>& v) {
std::transform(v.begin(), v.end(), v.begin(),
[](double d) {
if (d < 0.0001) {
return 0;
} else {
return d;
}
});
}
これを解決するために、ラムダ関数の戻り値の型を明示的に指定することができます。
-> T
:
void func4(std::vector<double>& v) {
std::transform(v.begin(), v.end(), v.begin(),
[](double d) -> double {
if (d < 0.0001) {
return 0;
} else {
return d;
}
});
}
変数の捕捉
ここまでは、ラムダに渡されたもの以外をラムダ内で使っていなかったが、ラムダ内で、他の変数を使うこともできる。他の変数にアクセスしたい場合は、capture節(
[]
の式)は、これまでのところ、この例では使われていません、例えば。
void func5(std::vector<double>& v, const double& epsilon) {
std::transform(v.begin(), v.end(), v.begin(),
[epsilon](double d) -> double {
if (d < epsilon) {
return 0;
} else {
return d;
}
});
}
参照と値の両方によるキャプチャが可能で、その指定は
&
と
=
をそれぞれ作成します。
-
[&epsilon, zeta]
参照でイプシロン、値でゼータをキャプチャします。 -
[&]
ラムダで使用されているすべての変数を参照で取得します。 -
[=]
ラムダで使用されているすべての変数を値で捕捉します。 -
[&, epsilon]
ラムダで使用されているすべての変数を参照でキャプチャし、イプシロンを値でキャプチャします。 -
[=, &epsilon]
ラムダで使用されるすべての変数を値でキャプチャしますが、参照によってイプシロンをキャプチャします。
生成された
operator()
は
const
はデフォルトで、キャプチャーが
const
にアクセスすると、デフォルトで これは、同じ入力で呼び出すと同じ結果になるという効果がありますが、次のようにすることができます。
としてラムダをマークします。
mutable
を要求するために
operator()
を生成することはできません。
const
.
関連
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】C++でint型に無限大を設定する
-
[解決済み】C++ 非推奨の文字列定数から「char*」への変換について
-
[解決済み】Visual Studio 2015で「非標準の構文; '&'を使用してメンバーへのポインターを作成します」エラー
-
[解決済み】C++でランダムな2倍数を生成する
-
[解決済み】抽象クラス型の無効なnew-expression
-
[解決済み】リンカーエラーです。"リンカ入力ファイルはリンクが行われていないため未使用"、そのファイル内の関数への未定義参照
-
[解決済み】ファイルから整数を読み込んで配列に格納する C++ 【クローズド
-
[解決済み] 非静的データメンバの無効な使用
-
[解決済み】システムが指定されたファイルを見つけられませんでした。
-
[解決済み】C++ - 適切なデフォルトコンストラクタがない [重複]。