lvalue reference became invalid after passing through an identity function

The problem is your lambda. It doesn’t do what you think it does:

function<const A&(const A& r)> foo1 = [](const A& r) { 
//                                               ~~~~~~
    return r;
};

Note that there’s no trailing return type. That means that it’s automatically deduced. Deduction never gives you a reference type, so this lambda returns an A, not an A const&. That returned temporary A is then bound to the return A const& of function‘s operator(). That temporary is not lifetime-extended. But the time we finish calling foo1(), we have a dangling reference to that temporary A. This is undefined behavior, which I guess with your compiler, gave you a helpful runtime error.

To fix this, you need to explicitly specify the return type:

function<const A&(const A& r)> foo1 = [](const A& r) -> A const& { 
    return r;
};

But even this is dangerous, since you can still pass a temporary A into this function and get a dangling reference out. No real way around that one.


The ease of falling into this trap is also LWG Issue 2813

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)