Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

segment fault when passing right reference for literal in labmda with varidic template function

Tags:

c++

c++11

lambda

the code is as follows

#include <functional>
#include <iostream>

using namespace std;
int foo(int a){
    cout<<a;
    return a;
}

template<typename R, typename ...Args>
function<void()> wrapper( R f, Args&& ... args) {
    function<void()> fun([&] { f(forward<Args...>(args...)); });//crash
    //function<void()> fun=bind(f,forward<Args...>(args...));
    return fun;
}

int main(){
    auto d=wrapper(foo,1);
    d();
    return 0;
}

when I use bind, all is fine. but when I use lambda the program crash. I wonder there is a way to capture variable by reference for lambda but capture literal by value(for efficiency)? Or should I stick with bind?

like image 459
Kwan Avatar asked Feb 02 '26 19:02

Kwan


1 Answers

function<void()> fun([&] { f(forward<Args...>(args...)); });//crash

All of these captured objects, f and all args, are captured by reference.

All of them are parameters to wrapper.

But as soon as wrapper returns, all parameters to wrapper go out of scope and get destroyed. And your lambda's captured references, all of them, become dangling references.

I might see some wiggle room here, possibly, when wrapper's parameters that could be references themselves, with the lambda then capturing a reference to the original object, and not the wrapper parameter itself.

But nothing guarantees that, here.

As such, this all but guarantees undefined behavior.

It is true that there is syntax to capture f by value, and everything else by reference, but this will not help you.

auto d=wrapper(foo,1);

Because even in this case, the one you're working with, your parameter is a prvalue, which will vanish in a puff of smoke when wrapper returns, leaving your lambda with an empty bag, holding a dangling reference.

You have no realistic options here except to capture everything by value.

like image 121
Sam Varshavchik Avatar answered Feb 04 '26 11:02

Sam Varshavchik