Yes, it's undefined behaviour, since the references inside the lambdas become dangling as soon as captureFunc()
exits (*).
What's probably happening in your case is that the references (which are just pointers under the hood) still point to the space on the stack where i
was on the first invocation of captureFunc()
, and it ends up in exactly the same location on the second invocation of captureFunc()
; so the net effect is that all of get1
, get2
, set1
, set2
have their internal i
reference pointed to the same (currently unused) location in memory, so they modify it for each other.
Of course, the above is just speculation, and could change next time you (or run) the program, since Undefined Behaviour is Undefined.
(*) Quoting C++11, [expr.prim.lambda]§22:
[ Note: If an entity is implicitly or explicitly captured by reference, invoking the function call operator of the corresponding lambda-expression after the lifetime of the entity has ended is likely to result in undefined behavior. —end note ]