Consider the following code:
#include <iostream> struct test { void public_test() { [this]() { private_test(); }(); } private: void private_test() { std::cout << "test\n"; } }; int main() { test().public_test(); }
The lambda captures this and then calls a private method of the captured object. Now this code compiles and works (prints test
) using VC++ 2012. Whereas this is quite intuitive and useful behaviour, I'd like to know if this is guaranteed to work by standard. Thus, does a lambda have private access to any object captured through this
?
I tried to look this up in the standard reading through 5.1.2 [expr.prim.lambda] but could not really find a definite answer (being not that well-versed in the depths of the standard). The only paragraph that seemed useful to me is
The type of the lambda-expression (which is also the type of the closure object) is a unique, unnamed nonunion class type — called the closure type — whose properties are described below. This class type is not an aggregate (8.5.1). The closure type is declared in the smallest block scope, class scope, or namespace scope that contains the corresponding lambda-expression. [ Note: This determines the set of namespaces and classes associated with the closure type (3.4.2). The parameter types of a lambda-declarator do not affect these associated namespaces and classes. —end note ]
But on the other a normal local class type defined in a member function doesn't have private access to the surrounding class. So a lambda having private access would somehow raise lambdas above mere syntactic sugar for a local function object to something more involved, since it would need additional "compiler magic" to somehow make it a friend of the surrounding class.
So does a lambda have private access to any object captured through this
and if yes, which parts of the standard allow this happen?
The lambda is capturing an outside variable. A lambda is a syntax for creating a class. Capturing a variable means that variable is passed to the constructor for that class. A lambda can specify whether it's passed by reference or by value.
C++ Lambda expression allows us to define anonymous function objects (functors) which can either be used inline or passed as an argument. Lambda expression was introduced in C++11 for creating anonymous functors in a more convenient and concise way.
The context of a lambda is the set of objects that are in scope when the lambda is called. The context objects may be captured then used as part of the lambda's processing. Capturing an object by name makes a lambda-local copy of the object. Capturing an object by reference allows the lambda to manipulate its context.
One of the new features introduced in Modern C++ starting from C++11 is Lambda Expression. It is a convenient way to define an anonymous function object or functor. It is convenient because we can define it locally where we want to call it or pass it to a function as an argument.
I don't think the fact that it is a lambda is relevant. All lambda does is define a local class. And according to §11/2: "A local class of a member function may access the same names that the member function itself may access."
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With