C++ でのラムダ式
Visual C++ では、が状態を保持する ラムダあり、外側のスコープに使用できる変数にアクセスできる匿名関数のようとしてラムダ式を参照する。ここでは、ラムダであるかを定義し、他のプログラミング手法と比較し、利点を説明し、基本的な例を示します。
ラムダについて
多くのプログラミング言語は本体がある、サポートされる名前がありません関数である 匿名関数の概念が。ラムダは匿名関数に関連するプログラミング手法です。ラムダ関数は暗黙的にオブジェクトのクラスを定義し、そのクラスの型関数オブジェクトを構築します。関数のオブジェクトの詳細については、関数オブジェクト"を参照してください。
重要 |
---|
ラムダは、次の共通言語ランタイムの (CLR) のマネージ エンティティではサポートされていません: ref class、ref struct、value class、または value struct。 |
関数オブジェクトと. ラムダ
コードを記述する場合、特に [STL algorithms]を使用すると、関数ポインター、および問題を解決するには、計算を実行するために関数のオブジェクトを使用します。関数ポインターと関数オブジェクトに利点と欠点例では、関数ポインターに最小限の構文のオーバーヘッドがありますが、スコープ内の状態を継続し、関数オブジェクトは、状態を保持し、クラス定義の構文のオーバーヘッドを要求できます。
ラムダは、関数ポインターと関数のオブジェクトの利点をまとめ、欠点を回避できます。関数のように変換するラムダは、柔軟で状態を保持できますが、関数オブジェクトとは異なり、簡易構文は、クラス定義は必要ではありません。ラムダを使用して、あまり使いにくく、同等の関数オブジェクトのコードよりエラーが発生しやすいコードを作成できます。
次の例では、関数オブジェクトを使用してラムダの使用を比較します。最初の例は vector のオブジェクトの各要素が偶数か奇数であるかをコンソールに出力するには、ラムダを使用します。2 番目の例は同じタスクを実行するには、関数のオブジェクトを使用します。
例 1: ラムダを使用する
この例では vector オブジェクトの各要素は、偶数か奇数であるかどうか for_each の関数呼び出しでコンソールに出力するには埋め込まれたラムダを使用します。
コード
// even_lambda.cpp
// compile with: cl /EHsc /nologo /W4 /MTd
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
int main()
{
// Create a vector object that contains 10 elements.
vector<int> v;
for (int i = 0; i < 10; ++i) {
v.push_back(i);
}
// Count the number of even numbers in the vector by
// using the for_each function and a lambda.
int evenCount = 0;
for_each(v.begin(), v.end(), [&evenCount] (int n) {
cout << n;
if (n % 2 == 0) {
cout << " is even " << endl;
++evenCount;
} else {
cout << " is odd " << endl;
}
});
// Print the count of even numbers to the console.
cout << "There are " << evenCount
<< " even numbers in the vector." << endl;
}
出力
0 is even
1 is odd
2 is even
3 is odd
4 is even
5 is odd
6 is even
7 is odd
8 is even
9 is odd
There are 5 even numbers in the vector.
コメント
例では、for_each 関数への 3 番目の引数は、ラムダです。[&evenCount] の部分は、capture 句の式を指定します (int n) はパラメーター リストを指定し、残りの部分は、式の本体を指定します。
例 2: 関数オブジェクトを使用する
ラムダは、前の例よりもはるかにそれ以上を拡張するには、複雑になります。次の例は、for_each の関数とともに、ラムダの代わりに例 1.と同じ結果を生成するには、関数のオブジェクトを使用します。どちらの例でも vector のオブジェクトに含まれる偶数の数を格納します。操作の状態を保持するには、FunctorClass のクラスはメンバー変数として参照によって m_evenCount の変数を格納します。操作を実行するには、FunctorClass は、関数呼び出し演算子を実装します operator()。Visual C++ コンパイラでは、例 1.のラムダ コードに匹敵パフォーマンスに影響を与えるコードを生成します。基本的な問題についてこの記事の 1 を、単純なラムダのデザイン、関数、オブジェクトなどのデザイン方法が適切です。ただし、重要な機能拡張を後で要求される可能性があると考えられる場合はコードの保守が容易になるように、その関数オブジェクトのデザインを使用します。
operator() の詳細については、「関数呼び出し (C++)」を参照してください。for_each 関数の詳細については、「for_each」を参照してください。
コード
// even_functor.cpp
// compile with: /EHsc
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
class FunctorClass
{
public:
// The required constructor for this example.
explicit FunctorClass(int& evenCount)
: m_evenCount(evenCount)
{
}
// The function-call operator prints whether the number is
// even or odd. If the number is even, this method updates
// the counter.
void operator()(int n) const
{
cout << n;
if (n % 2 == 0) {
cout << " is even " << endl;
++m_evenCount;
} else {
cout << " is odd " << endl;
}
}
private:
// Default assignment operator to silence warning C4512.
FunctorClass& operator=(const FunctorClass&);
int& m_evenCount; // the number of even variables in the vector.
};
int main()
{
// Create a vector object that contains 10 elements.
vector<int> v;
for (int i = 0; i < 10; ++i) {
v.push_back(i);
}
// Count the number of even numbers in the vector by
// using the for_each function and a function object.
int evenCount = 0;
for_each(v.begin(), v.end(), FunctorClass(evenCount));
// Print the count of even numbers to the console.
cout << "There are " << evenCount
<< " even numbers in the vector." << endl;
}
概要
ラムダは強力で、表現力が豊かなプログラミング手法です。ラムダ パーツとプロパティについて学習するには、ラムダ式の構文を参照してください。詳細については、プログラムでラムダを使用する方法を ラムダ式の例を参照してください。