The code below crashes when the lamdba f
is called.
However, my expectation is that since the parameter pack is captured by value inside the "wrapper" function, it should have worked fine!
Could someone help with the correct understanding?
void argPrinter(double d, int v, bool b) {
cout << "argPrinter: " << " " << d << " " << v << " " << b << endl;
}
template <typename Callable, typename... Args>
auto wrapper(Callable op, Args&&... args) {
auto result = [&op, args...] () mutable {
// args... are captured by value.
cout << "Hello\n";
op(args...);
};
return result;
}
int main() {
auto f = wrapper(argPrinter, 28.7, -99, true);
f(); // **SIGSEGV at this call!!**
}
The issue is not the parameter pack, but rather the capture of op
.
The function wrapper
accepts the Callable op
parameter by value.
But the lambda result
in it captures it by reference (&op
). This means that the capture is referencing the wrapper
function argument op
, which gets out of scope when the function returns.
Your lambda now holds a dangling reference to it.
In order to solve it you can change the lambda capture of op
to be by value.
This seems like a straightforward thing to do anyway, as you already passed it by value to wrapper
:
//-------------vv----------------------
auto result = [op, args...]() mutable {