このセクションの誊弄はλライブラリの答塑弄な怠墙を疽拆することである。 毋嘲祸灌や泼侍な眷圭も润撅にたくさんあるが、それらの厦玛については稿のセクションにまわすことにする。
このセクションでは、STL アルゴリズムの钙叫しにおける、BLL のλ及の答塑弄な毋を绩す。 いくつかの帽姐な及から幌めて、靳」に券鸥させていく。 まず、コンテナ( 毋えば list ) の妥燎を 1 に介袋步してみる。
list<int> v(10); for_each(v.begin(), v.end(), _1 = 1);及 _1 = 1 が栏喇したλファンクタを网脱して、v の称妥燎に 1 を洛掐している。 [1]
肌に、ポインタのコンテナを侯喇し、そのポインタを黎镍のコンテナ v の妥燎を回すようにする。
vector<int*> vp(10); transform(v.begin(), v.end(), vp.begin(), &_1);&_1という及は、vのそれぞれの妥燎のアドレスを艰评する簇眶オブジェクトを栏喇する。 そして、そのアドレスは滦炳するvpの妥燎に洛掐される。
肌のコ〖ドは v の妥燎の猛を恃步させる。 それぞれの妥燎に滦して、簇眶foo が钙ばれる。 fooには、称妥燎の猛が苞眶として畔され、その冯蔡は苞眶として畔された妥燎に洛掐される。
int foo(int); for_each(v.begin(), v.end(), _1 = bind(foo, _1));
肌に、vp の妥燎のソ〖トを乖う。
sort(vp.begin(), vp.end(), *_1 > *_2);このsortの钙叫しでは、妥燎をポインタの回す柒推の惯界でソ〖トする。
呵稿に、肌の for_each の钙叫しでは、ソ〖トされた vp の妥燎の回す柒推を猖乖惰磊りで叫蜗する。
for_each(vp.begin(), vp.end(), cout << *_1 << '\n');λ及の婶尸及で奶撅の及( λ及でない )ものは篓郝に删擦されることに庙罢しなければならない。 そうしないと、徒袋しない冯蔡を瞥いてしまう。 毋えば、黎の毋を肌のように今垂えてみると、 婶尸及cout << << '\n' は篓郝に删擦されてしまう。 その冯蔡、办つの猖乖とそれに鲁けて vp の妥燎が叫蜗されてしまう。
for_each(vp.begin(), vp.end(), cout << '\n' << *_1);BLL では簇眶 constant と簇眶 var が捏丁されており、それぞれ年眶と恃眶をλ及へと恃垂する。 これらの簇眶を蝗脱することにより、婶尸及が篓郝に删擦されてしまうことを松贿できる。
for_each(vp.begin(), vp.end(), cout << constant('\n') << *_1);これらの簇眶は Section 5.5 でより拒しく淡揭する。
λファンクタの钙叫しの粗は、悸苞眶はプレ〖スホルダ〖として藐据步されている。 プレ〖スホルダ〖は悸苞眶の房には逼读を涂えない。 答塑弄には、藐据步されたλ及が C++ の铜跟な及であるかぎり、λ簇眶はいかなる房の苞眶をともなっても钙ぶことができる。 毋えば、 _1 + _2 は、企灌λファンクタを栏喇する。 このファンクタはいかなる房 A と 房B の企つのオブジェ クトと鼎に钙叫すことができる。これらの房には operator+(A,B) が年盗されていればよい。(そして、BLL がその遍换灰の手り猛を急侍できれ ばよい。拒しくは笆布を斧よ。)
C++ には及の房を啼圭せるメカニズムが赂哼しない。 しかし、まさにこの怠墙は C++ のλ及の悸刘には端めて脚络である。 よって、BLL は泼拉クラスの礁圭を蝗脱してλ簇眶の手り猛の房を夸侠するちょっとした剩花な房夸侠システムを柒蜀している。 その夸侠システムは、オペランドが寥み哈み房である及と、オペランドが筛洁ライブラリの房をオペランドとする及である及を胺う。 驴くのユ〖ザ年盗房も、泼にユ〖ザ年盗の遍换灰が奶撅の捶毋に骄っていれば、票屯に滦炳している。
しかしながら、手り猛の房を夸侠できない眷圭が赂哼する。 毋えば、肌のように年盗をしたとすると、
C operator+(A, B);肌のλファンクタの钙叫しは、手り猛の房を夸侠できないために己窃する。
A a; B b; (_1 + _2)(a, b);
これを豺疯するには企つの洛仑捌がある。 办つ誊は、BLL の房夸侠システムを迫极の房に滦炳するために橙磨することで ある (拒しくは Section 6 を斧よ)。 企つ誊の数恕は肌のように泼侍なλ及 ret を蝗脱することである。
A a; B b; ret<C>(_1 + _2)(a, b);このλ及は房夸侠システムに洛わって、手り猛の房を疯年する。 (拒しくは Section 5.4 を斧よ)
bind 及に簇しては、手り猛の房はテンプレ〖ト苞眶として肌のように回年す ることができる。
bind<int>(foo, _1, _2);
办忍弄な悸苞眶の扩嘎は、悸苞眶には润 const な宝收猛を回年できない。 毋えば、
int i = 1; int j = 2; (_1 + _2)(i, j); // ok (_1 + _2)(1, 2); // error (!)である。 この扩嘎はそれほど碍いものではない。 λファンクタはたいていの眷圭、STL のアルゴリズム面で钙叫されるため、苞眶はイテレ〖タを徊救嘲ししたものであり、徊救嘲しの拎侯が宝收猛を手すことはほとんどないからである。 そして、宝收猛を手すような眷圭には、Section 5.9.2で揭べるような洛仑捌がある。
デフォルトの瓢侯では、芦躯された苞眶の const な办箕弄なコピ〖が、λファンクタ面に呈羌される。 つまり、芦躯された苞眶の猛は、λ簇眶の栏喇箕に盖年され、かつ、λ簇眶オブジェクトのライフタイムの粗は年眶であり鲁けるということである。 毋えば、
int i = 1; (_1 + i)(i = 2);呵稿の乖の及の猛は 4 ではなく、3 である。 咐い垂えると、λ及 _1 + iは lambda x.x+iではなく、 lambda x.x+1というλ簇眶を栏喇する。
黎に揭べたように、これはあくまでデフォルトの瓢侯であって、毋嘲もある。 赖澄な惮搂は肌のようになる。
プログラマはref や cref のラッパ[ref]を蝗脱することにより、呈羌のメカニズムを拎侯することができる。 苞眶を ref や crefでラップすることにより、苞眶をそれぞれ徊救として、const への徊救として呈羌するように回年することができる。 毋えば、黎の毋の恃眶 i を ref でラップして今き木せば、 lambda x.x+iというλ及を侯喇し、呵稿の乖の及の猛は 4 となる。
i = 1; (_1 + ref(i))(i = 2);ref と cref は var や constant とは佰ることに庙罢しなければならない。 稿荚は、λファンクタを栏喇するのに滦し、涟荚はそうではない。 毋えば、
int i; var(i) = 1; // ok ref(i) = 1; // not ok, ref(i) is not a lambda functorとなる。 簇眶ref と cref はほとんど悟凰弄な妄统からのみ赂哼している。 そして、ref は var で cref は constant_refで弥き垂えることができる。 拒しくは Section 5.5 を斧よ。 ref と cref は Boost の绕脱弄な誊弄のユ〖ティリティ〖簇眶であるので、boost ネ〖ムスペ〖スに木儡年盗されている。
芹误房はコピ〖することはできず、デフォルトの瓢侯では、const な徊救として呈羌される。
いくつかの及については、苞眶を徊救として呈羌するほうが羌评がいく。 毋えば、λ及 i += _1の罢哭は汤らかに、λファンクタの钙叫しにより、办箕弄なコピ〖ではなく、恃眶iそのものの猛に逼读を涂えることである。 侍な毋を刁げると、ストリ〖ムの遍换灰は const でない徊救として呵焊の苞眶をとる。 赖澄な惮搂は肌のようになる。
剩圭洛掐遍换灰(+= や *= など)の焊娄の苞眶は、const でない徊救として呈羌される。
<< 第び >> の焊の苞眶がそれぞれ、 悸挛步された basic_ostream 第び basic_istream から 巧栏している眷圭には、その苞眶は润 const への徊救として呈羌される。 その戮の房に簇しては、苞眶はコピ〖として呈羌される。
[1] 阜泰には、C++ 筛洁惮呈では、for_each は 恃构のない息鲁拎侯 であり、 for_eachへ畔す簇眶オブジェクトはその苞眶をを恃构すべきでないと年盗されている。 この苞眶に滦する妥滇は稍涩妥に阜しすぎる。 なぜなら、イテレ〖タが mutable である嘎り、for_each は苞眶への甥侯脱のある簇眶オブジュクトも借妄できるからである。 とはいえ、std::for_each の怠墙を积つが、苞眶に滦してより努磊な妥滇を积 つような、侍の簇眶テンプレ〖トを捏丁することは词帽である。