The problem is in the way you capture things in your lambda.
a(Y X::*field): f([&](const X &x) { return x.*field; }) {}
You use a reference to field
, which is valid only in the constructor. When the constructor ends, you have a dangling reference.
A way to fix would be to copy parameters :
a(Y X::*field): f([=](const X &x) { return x.*field; }) {}
The creation of a3
fails because you do not have appropriate constructor.