Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Repeatedly moving a variable from lambda that has been move captured

I have the following test code:

#include <iostream>
#include <string>

void printValue(std::string&& val)
{
    std::cout << "Got value: " << val << "\n";
}

int main() {

    std::string testValue = "Test Value";

    auto lambda = [testValue = std::move(testValue)]() mutable
    {
        printValue(std::move(testValue));
    };

    lambda();
    lambda();
    lambda();
}

I get the result:

Got value: Test Value
Got value: Test Value
Got value: Test Value

It it a valid assumption that moving an object from within lambda that has been move captured will always have the initial state that it was moved into the lambda with, or is this just an artifact of an object being in "valid but unspecified state"?

like image 319
dempzorz Avatar asked Apr 16 '18 01:04

dempzorz


1 Answers

std::move doesn't perform move operation; it just converts the argument to an rvalue. For your code, printValue takes the parameter by rvalue-reference, so the argument testValue will be passed via the reference. But the move operation is not performed on it then testValue won't get changed.

If you change val to pass-by-value, then the argument testValue will be moved into val, or you can add move operation explicitly like

void printValue(std::string&& val)
{
    std::cout << "Got value: " << val << "\n";
    std::string x = std::move(val);            // perform move operation on val
}

Both would cause the move operation to be performed 3 times, then you'll get different result, e.g. with clang,

Got value: Test Value
Got value: 
Got value: 

PS: As you said, after being move-constructed-from the object will be left in valid but unspecified state. The behavior above is not guaranteed by the standard although most implementations do so.

like image 174
songyuanyao Avatar answered Nov 06 '22 09:11

songyuanyao