c++lambdac++20lambda-capture

lambda init capture with parameter pack


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!!**
}

Solution

  • 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 {
    

    Live demo