Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does adding std::move bring the capture back to the stack?

Given the following code that tries to allocate a lambda capture on the heap:

#include <array>
int test(void) {
    //auto big_lambda = new auto([d = std::array<int, 1024>{5,1,2}]() { return d[2]; });
    auto big_lambda = new auto(std::move([d = std::array<int, 1024>{5,1,2}]() { return d[2]; }));
    auto res = (*big_lambda)();
    delete big_lambda;
    return res;
}

Why does wrapping the lambda with std::move create the capture on the stack? Is it because std::move "materializes" the temporary lambda before it's passed on to the move (I think?) constructor?

like image 542
Fullaccess Avatar asked Aug 10 '26 23:08

Fullaccess


1 Answers

std::move is not a cast. It performs a cast, but it is ultimately a function call. Which means it needs to follow the rules of a function call.

Function parameters cannot be prvalues. If an argument to a function is a prvalue, then it will manifest a temporary to fill in the parameter. And that's what is happening here.

There's no need to use std::move in any case. Broadly speaking, the argument to std::move should always be a name. You move from a variable. Generalized expressions which you know are prvalues should not be moved from.

like image 185
Nicol Bolas Avatar answered Aug 12 '26 16:08

Nicol Bolas