I do not have access to the C ++ language specification at the moment, but the unauthorized website cppreference.com says:
http://en.cppreference.com/w/cpp/language/lambda
The lambda expression constructs an unnamed temporary object prvalue of a unique unnamed unrelated non-aggregate type, known as a closure type.
I know that the specification also states that only non-exciting lambdas can decompose into function pointers (copied from Positive lambda: '+ [] {}' - What witchcraft is this? ):
The closure type for a lambda expression without lambda capture has a public non-virtual implicit conversion function const, so that a pointer to a function that has the same parameter and return types as the closure function call statement. The value returned by this conversion function must be the address of a function that, when called, has the same effect as when calling the statement to call the close function.
In C # and C ++, the lambda method with variable capture (i.e. closure) looks like this when used (warning: C # / C ++ style pseudo-code) in front):
class Foo {
void AConventionalMethod() {
String x = null;
Int32 y = 456;
y = this.arrayOfStringsField.IndexOfFirstMatch( (element, index) => {
x = this.DoSomethingWithAString( element );
y += index;
return index > 5;
} );
}
}
This can be considered roughly equivalent:
class Closure {
Foo foo;
String x;
Int32 y;
Boolean Action(String element, Int32 index) {
this.x = this.foo.DoSomethingwithAString( element );
this.y += index;
return index > 5;
}
}
class Foo {
void AConventionalMethod() {
String x = null;
Int32 y = 456;
{
Closure closure = new Closure() { foo = this, x = x, y = y };
Int32 tempY = this.arrayOfStringsField.IndexOfFirstMatch( closure.Action );
x = closure.x;
y = closure.y;
y = tempY;
}
}
}
/ this
Closure::Action
. #, Delegate
, this
, ++ , std::function
( , this
) - - C- , , this
.
, - , - - - . , this
-saving Delegate
std::function
, :
void AConventionalMethod() {
void* frame;
frame = &frame;
string x = nullptr;
int32_t y = 456;
y = this.arrayOfStrings( lambdaAction );
}
static bool lambdaAction(void* frame, string element, int32_t index) {
Foo* foo = reintepret_cast<Foo*>( frame + 0 );
string* x = reintepret_cast<string*>( frame + 4 );
int32_t* y = reintepret_cast<int32_t*>( frame + 8 );
*x = foo->doSomethingWithAString( element );
*y = *y + index;
return index > 5;
}
: , , , Closure , - lambdaAction
- (ab) .
, , , : , , -, . , ( , ):
void AConventionalMethod() {
void* frame;
frame = &frame;
String x = null;
Int32 y = 456;
char wrapper[] = __asm {
push frame ; does not alter any existing arguments
; but pushes/adds 'frame' as a new
; argument, and in a right-to-left calling-
; convention order this means that 'frame'
; becomes the first argument for 'lambdaAction'
call lambdaAction
return ; EAX return value preserved
};
y = a_higher_order_function_with_C_style_function_pointer_parameter( wrapper );
}
static bool lambdaAction(void* frame, string element, int32_t index) {
}
wrapper
(, AConventionalMethod
), , .
:
, - - , - , ++ lambdas, C-style, , ? ( , )?