C++におけるラムダ式の解説
ラムダ式とは?
C++11で導入されたラムダ式は、無名関数の一種です。つまり、名前のない関数として定義し、直ちに呼び出すことができる関数です。その構文は、次のように表現されます。
[capture list](parameters) -> return type { body }
- capture list: ラムダ式が外部変数を参照できるかどうかを指定します。
- parameters: ラムダ式のパラメータリストです。
- return type: ラムダ式の戻り値の型です。
- body: ラムダ式の本体です。
ラムダ式を使用する場面
ラムダ式は、以下のような場面で特に有効です。
関数オブジェクトの生成:
- 匿名の関数オブジェクトを直接生成して、アルゴリズムや関数テンプレートに渡すことができます。
std::vector<int> numbers = {1, 2, 3, 4, 5}; std::sort(numbers.begin(), numbers.end(), [](int a, int b) { return a > b; });
遅延評価:
- ラムダ式は、呼び出されるまで評価されません。これは、計算コストの高い操作を必要に応じて遅延させる場合に便利です。
auto calculate_sum = [numbers]() { int sum = 0; for (int num : numbers) { sum += num; } return sum; }; // 実際に計算が必要なときだけ呼び出す int result = calculate_sum();
関数ポインタの代替:
標準ライブラリのアルゴリズムとの連携:
ラムダ式の利点
- 簡潔なコード: ラムダ式は、関数オブジェクトを定義する手間を省くことができます。
- 柔軟性: ラムダ式は、さまざまな状況で使用することができ、コードの可読性を向上させることができます。
- 性能: 適切に使用することで、パフォーマンスの向上を実現することができます。
[capture list](parameters) -> return type { body }
ラムダ式の代替方法
ラムダ式は、C++11で導入された便利な機能ですが、必ずしも使用しなければならないわけではありません。以下では、ラムダ式を使用しない場合の代替方法について解説します。
名前付き関数
最も直接的な代替方法は、名前付き関数を使用することです。ラムダ式と同じ機能を実現するために、関数定義を作成することができます。
// ラムダ式の代わりに名前付き関数を使用
bool compare(int a, int b) {
return a > b;
}
std::vector<int> numbers = {1, 2, 3, 4, 5};
std::sort(numbers.begin(), numbers.end(), compare);
関数オブジェクト
ラムダ式と同様、関数オブジェクトを使用することもできます。関数オブジェクトは、演算子オーバーロードを使用して関数のように呼び出すことができるクラスです。
// 関数オブジェクト
class GreaterThan {
public:
bool operator()(int a, int b) const {
return a > b;
}
};
std::vector<int> numbers = {1, 2, 3, 4, 5};
std::sort(numbers.begin(), numbers.end(), GreaterThan());
関数ポインタ
関数ポインタは、関数のアドレスを保持する変数です。関数ポインタを使用することで、関数への参照を関数オブジェクトの代わりに渡すことができます。
// 関数ポインタ
bool compare(int a, int b) {
return a > b;
}
std::vector<int> numbers = {1, 2, 3, 4, 5};
std::sort(numbers.begin(), numbers.end(), compare);
std::function
C++11では、std::function
テンプレートクラスを使用して、関数やラムダ式、関数オブジェクトを汎用的に扱うことができます。
// std::function
std::function<bool(int, int)> compare = [](int a, int b) { return a > b; };
std::vector<int> numbers = {1, 2, 3, 4, 5};
std::sort(numbers.begin(), numbers.end(), compare);
これらの代替方法と比較して、ラムダ式を使用する利点は次のとおりです。
- 簡潔性: ラムダ式は、名前付き関数を定義するよりも簡潔に記述できます。
- 匿名性: ラムダ式は、名前がないため、一時的な関数として使用することができます。
- キャプチャ: ラムダ式は、外部変数をキャプチャして使用することができます。
- 自動型推論: ラムダ式の戻り値型は、自動的に推論されます。
c++ lambda c++11