class A {
public:
int a;
char b;
double c;
A ( int x, char y, double z ) : a(x), b(y), c(z){}
};
int main(){
auto lambda = []( auto x ) {
static auto y = x;
// y = x;
return y;
};
int a = lambda(1);
char b = lambda('a');
double c = lambda(1.5);
A d = lambda( A( 2, 'b', 2.5 ) );
return 0;
}
This code compiles in Clang 3.8.0 and GCC 5.4.0, and works fine. However, taking into account that variable y
is static
:
y
? Does the type of y
change in every call to the lambda?y
initialized in every call in spite of being static
? The commented assignment // y = x
is not needed to update the value of variable y
.If I print the sizeof(y)
in each call I get 4, 1, 8 and 16 respectively.
Your lambda is generic. Which means that this is a template in disguise. The situation is handled in accordance with general rules for template specializations.
For every specific deduced type of parameter x
you get a separate specialization of your function. So, yes for each specific type of x
you get a separate copy of y
. But the underlying mechanism is not somehow localized at your static
, it is the whole body of your function that gets "copied" to produce a separate independent implementation of the function.
Each specialization of your lambda will have a separate copy of y
, which will be initialized only once at the first call to that specific specialization.
The situation is virtually equivalent to a more explicit
template <typename T> void foo(T x)
{
static T y = x;
std::cout << y << std::endl;
}
int main()
{
foo(1);
foo('a');
foo(1.5);
foo(3.0);
}
which outputs 1
, a
, 1.5
and 1.5
.
In this example you get three independent specializations of foo
: foo<int>
, foo<char>
and foo<double>
. Each version of foo
gets its own version of y
, meaning that there are three different static y
s in this example. The first call to each specialization will initialize y
and the subsequent calls will not re-initialize it. In this case call to foo(1.5)
initializes y
for foo<double>
, but the subsequent call to foo(3.0)
does not.
The same thing happens in your case as well, it just uses a different syntax.