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"?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With