C ++ラムダアプリケーションシナリオおよびコンパイラの実装原則として

まず、利用シーン

ローカル関数の1シーンの要件および制限

(11 C ++前)標準C ++では、構文は、ローカル関数ではありません。しかし、いくつかのシナリオでは、ローカル関数を使用すると大幅にコードを簡素化することができ、例えば、円(中心点と半径で表される)は、入力パラメータであり、2点所定の円の外側にいるかどうか、判断される、内部、この場合、好ましくは円形インタフェース、2点の内側の点は、それぞれ判断するかどうかを決定する機能を有します。
点構造体
{
int型X;
INT Y;
};
BOOL IsTrue(ポイント&rstCenter、INT iRadius、&ポイントP1およびP2と点)
{
BOOL PointInCircle(ポイント&rstPoint)
{
リターン(rstPoint.x - rstCenter.x)*(rstPoint.x - rstCenter.x)+(rstPoint.y - rstCenter.y)*(rstPoint.y - rstCenter.y)<* = iRadius iRadius;
}
戻りPointInCircle(PL)= PointInCircle(P2);!
}

C ++は、ローカル関数の使用を許可していないためしかし、上記のコードはコンパイルされません。静的関数の局所使用などのラムダ関数、一般的にこの問題を回避する部分的に画定されたタイプ、および機能の導入の前に、しかし、ここでローカル変数の関数を使用するように限定されるものではありません。
ハリー@ tsecer:CAT -n localstruct.cpp
1構造体ポイント。
2 {
3 int型のX;
4 INT Y;
5。};
6 BOOL IsTrue(ポイント&rstCenter、INT iRadius、ポイント&P1の、ポイント&P2)。
7 {
8構造体localstruct。
9 {
10 BOOL PointInCircle静的(ポイント&rstPoint)
。11 {
12リターンある(rstPoint.x - rstCenter.x)*(rstPoint.x - rstCenter.x)+(rstPoint.y - rstCenter.y)*(rstPoint.y - rstCenter.y) <* = iRadius iRadius;
13である}
14};
15 :: PointInCircleリターンlocalstruct(PL)= localstruct :: PointInCircle(P2);!
16}
ハリーtsecer @:G ++ localstruct.cpp -C
localstruct.cpp:在静态成员函数'静的なブールIsTrue(ポイント&、int型、ポイント&、ポイント&):: localstruct :: PointInCircle(ポイント&')中:
localstruct.cpp:12:25:错误:含む関数からのパラメータの使用
リターン(rstPoint.x - rstCenter.x)*(rstPoint.x - rstCenter.x)+(rstPoint.y - rstCenter.y)*(rstPoint.y - rstCenter.y)<= iRadius * iRadius。
^
localstruct.cpp:6:6:错误: 'ポイント&rstCenter'已在此声明过
BOOL IsTrue(ポイント&rstCenter、INT iRadius、ポイント&P1、ポイント&P2)
^
localstruct.cpp:12:54:错误:パラメーターの使用から含有関数
リターン(rstPoint.x - rstCenter.x)*(rstPoint.x - rstCenter.x)+(rstPoint.y - rstCenter.y)*(rstPoint.y - rstCenter.y)<= iRadius * iRadius。
^
localstruct.cpp:6:6:错误:「ポイント&
BOOL IsTrue(ポイント&rstCenter、INT iRadius、ポイント&P1、ポイント&P2)
^
localstruct.cpp:12:83:错误:関数を含むからのパラメータを使用する
リターン(rstPoint.x - rstCenter.x)*(rstPoint.x - rstCenterを。 X)+(rstPoint.y - rstCenter.y)*(rstPoint.y - rstCenter.y)<= iRadius * iRadius。
^
localstruct.cpp:6:6:错误: 'ポイント&rstCenter'已在此声明过
BOOL IsTrue(ポイント&rstCenter、INT iRadius、ポイント&P1、ポイント&P2)
^
localstruct.cpp:12:112:错误:パラメーターの使用から含有関数
リターン(rstPoint.x - rstCenter.x)*(rstPoint.x - rstCenter.x)+(rstPoint.y - rstCenter.y)*(rstPoint.y - rstCenter.y)<= iRadius * iRadius。
^
localstruct.cpp:6:6:错误: 'ポイント&rstCenter'已在此声明过
IsTrue BOOL(ポイント&rstCenter、int型iRadius、&ポイントP1およびP2&ポイント)
^
localstruct.cpp:12です:128:エラー:から含む関数のパラメータを使用
リターン(rstPoint.x - rstCenter.x)*(rstPoint.x - rstCenter。 X)+(rstPoint.y - rstCenter.y)*(rstPoint.y - rstCenter.y)<* = iRadius iRadius;
^
localstruct.cpp :. 6 :. 6:エラー: 'int型iRadiusは'ここで宣言された
ブールIsTrue (ポイント&rstCenter、INT iRadius、&ポイントP1およびP2&ポイント)
^
localstruct.cpp:12である:138:エラー:を含む関数のパラメータを使用
リターン(rstPoint.x - rstCenter.x)*(rstPoint.x - rstCenter.x) +(rstPoint.y - rstCenter.y)*(rstPoint.y - rstCenter.y)<* = iRadius iRadius;
^
localstruct.cpp :. 6 :. 6:エラー: 'int型iRadius'がここで宣言されています
BOOL IsTrue(ポイント&rstCenter、int型iRadius、ポイント&P1、ポイント&P2)
^
tsecer @ハリー:

 

2、ラムダ関数の溶液

tsecer @ハリー:猫-n locallambda.cpp
1のstructポイント
2 {
3のint X;
4 INT Y。
5}。
6
7 BOOL IsTrue(ポイント&rstCenter、INT iRadius、ポイント&P1、ポイント&P2)
8 {
9オートPointInCircle = [b](ポイント&rstPoint) - > BOOL
10 {
11リターン(rstPoint.x - rstCenter.x)*(rstPoint。 X - rstCenter.x)+(rstPoint.y - rstCenter.y)*(rstPoint.y - rstCenter.y)<= iRadius * iRadius。
12}。
13リターンPointInCircle(P1)= PointInCircle(P2)!。
14}
ハリー@ tsecer:G ++ -c -std = C ++ 11 locallambda.cpp
tsecer @ハリー:
ハリー@ tsecer。

第二に、実現原理

一般GCCがローカル変数に対応する構造でこれらの変数を捕捉、捕捉することによって宣言ステートメント関数への参照、関数演算を可能にし、構造体に定義するラムダ機能を実現する、話します。これらの外観は、同様の達成するために自分自身を比較し、その差は、それはローカル変数の参照の明確な声明を考慮して、構文を追加することで、機能は、対応するタイプとオペレータコンパイル時に生成するローカル変数を引用し、自動的に計算ラムダ関数に役立ちます。
autofunc.cpp -n CAT:ハリーtsecer @
1つの#include <機能>
2
。3 ::機能STD <BOOL(INT、INT)>のtypedef stdFunc
。4
。5 int型のmain(int型のargc、char型のconst * ARGV [])
。6 {
7 int型A、B、C、D、
8オートFF = [b](INTのX、INT Y) - > BOOL
。9 {
10リターンX + Y + A + D;
11};
12である
13は、FF(0x1111、0x2222)であります;
14
15 FF = stdFunc stdff;
16 stdff(0x3333、0x4444);
17}。
ハリーtsecer @:G = C ++ ++ -g -std 11 autofunc.cppする。
ハリー@ tsecer:GDB ./a.out
GNUのGDB(GDB)のRed Hat Enterprise Linux 7.6.1-80.el7
著作権(C)2013 Free Software Foundationが、株式会社の
ライセンスGPLv3の+:GNU GPLバージョン3以降<http://gnu.org/licenses/gpl.html >
これはフリーソフトウェアです:あなたはそれを変更して再配布は自由です。
NOの保証は、法律で認められている範囲内に、あります。「コピーSHOW」と入力
し、詳細については、「ショーの保証を」。
このGDBは、 "x86_64の-のredhat-のlinux-gnuの"として設定されました。
バグが命令を報告するために、参照してください。
<http://www.gnu.org/software/gdb/bugs/> ...
/home/harry/study/autofunc/a.out...doneからシンボルを読み込みます。
主B(GDB)
0x400874にブレークポイント1:ファイルautofunc.cpp、ライン11
(GDB)R
起動プログラム。

autofunc.cppで(ARGC = 1、ARGV = 0x7fffffffe578)メインブレークポイント1:11
11}。
欠落している別のdebuginfos、使用:のdebuginfo-インストールのglibc-2.17-196.tl2.3.x86_64のlibgcc-4.8.5-4.el7.x86_64のlibstdc ++ - 4.8.5-4.el7.x86_64
(GDB)p型のFF
タイプ=構造体__lambda0 {
int型&__;
INT&__ D;
}
(GDB)S
13個のFF(0x1111、0x2222)。
(GDB)
__lambda0 ::演算子()(__closure = 0x7fffffffe460、X = 4369、Y = 8738)autofunc.cppで:10
10リターンX + Y + A + D。
(GDB)p型__closureの
タイプ= constの構造体__lambda0 {
INT&__。
INT&__ D;
} * CONST
(GDB)

これは、B、コンパイラは動的にこのような構造を生成するコンパイル参照FFラムダ機能するので、ローカル変数、ことがわかる
構造体__lambda0 {
; INT&__ A
INT&__ D;
BOOL演算子()(int型X、INT Y)は
{
リターンX __A __B + Y + +;
}
}
構造の分解このポインタはまた__closureとみなすことができます。

第三に、とstdライブラリの機能的相互作用

実装原理の後、私たちはそれを知っている、そしてそれははstd一緒に使用することができます::機能、および同じ演算子を使用した構造と関数呼び出しを定義します:
ハリー@ tsecer:CAT -n lambdabind.cppを
。1つの#include <機能>
2
STDのtypedef ::関数3 <整数(INT、INT)> stdFunc;
4。
5メインINT(INTのargc、char型のconst * ARGV [])。
6 {
7オートFF = [b](INT X) - > INT。
8 {
9。 X + ARGCリターン;
10};
11 stdFunc STD :: = stdffバインド(FF、STD :: _ ::プレースホルダ1);
12は、戻りstdff(11、22である。)であり、
13である}
14
ハリーtsecer @:G ++ = -g -std ++ 11 lambdabind.cpp C
tsecer @ハリー:./a.out
tsecer @ハリー:エコー$?
12

おすすめ

転載: www.cnblogs.com/tsecer/p/12157887.html