ラムダ関数とc ++ 11でのその目的は理解していますが、「値の取得」と「引数の受け渡し」の違いはわかりません。例えば..
#include <iostream>
#include <functional>
using namespace std;
int add(int a,int b){
return a+b;
}
int main(int argc, char** argv){
function <int(int,int)> cppstyle;
cppstyle = add;
auto l = [] (function <int(int,int)> f,int a, int b) {return f(a,b);};
cout << l(cppstyle,10,30) <<"\n";
}
上記のコードの出力は、以下のコードと同じです。
#include <iostream>
#include <functional>
using namespace std;
int add(int a,int b){
return a+b;
}
int main(int argc, char** argv){
function <int(int,int)> cppstyle;
cppstyle = add;
auto l = [cppstyle] (int a, int b) {return cppstyle(a,b);};
cout << l(10,30) <<"\n";
}
「値の取得」は「値を引数として渡す」のと同じですか?またはキャプチャには特別な意味がありますか?
捕らえられた引数と引き渡される引数の違いは、類推で見ることができます。次の関数オブジェクトについて考えてみます。
_struct Capture {
int &i;
int const j;
public:
Capture(int &_i, int &_j) : i(_i), j(_j) {}
int operator()(int const a, int const b) {
i *= j;
return a * b;
}
};
_
関数オブジェクトクラスCapture
には、2つのメンバー変数i
とj
があります。 2つの入力引数を取るオーバーロードされたoperator()
もあります。次のラムダを考えてみましょう:
_int i, j;
[&i, j](int const a, int const b) {
i *= j;
return a * b;
};
_
クラスCapture
のメンバー変数は、ラムダキャプチャ(つまり、_[&i, j]
_)と類似していますが、オーバーロードされたoperator()
a
およびb
は、上記のラムダの入力引数a
およびb
と類似しています。
つまり、ラムダを関数オブジェクトと見なす場合、そのキャプチャは関数オブジェクト(つまり、そのメンバー変数)の状態ですが、その入力引数はオーバーロードされたoperator()
の入力引数になります。
より高いレベルでは、現在知っているデータをキャプチャし、電話をかける必要があるまで持っていないデータを渡します。
たとえば、ベクトル内のすべての数値に定数を追加したいとします。次のように書くことができます(注意:未テスト):
void Add(std::vector<int>& v, int i)
{
std::for_each(std::begin(v), std::end(v), [i](int& j){ j += i; });
}
I値のキャプチャは、ラムダが定義されたときに設定されますが、iが引数(j)として渡されると、ループ内で変化します。
#include <iostream>
using namespace std;
int main(int argc,char **argv) {
auto i=5;
auto f = [=](int j) {cout<<"capture i="<<i<<", passing i as j="<<j<< endl; };
while (i<30) {
i += 10;
f(i);
}
}
---これは出力になります:
ラムダキャプチャi = 5、iを引数j = 15として渡す
ラムダキャプチャi = 5、引数j = 25としてiを渡す
ラムダキャプチャi = 5、引数j = 35としてiを渡す