Do I really have to encapsulate the std::move call in a lambda?
std::list<std::wstring> srcData = GetData(); // implementation not important
std::vector<std::wstring> dstData;
dstData.reserve(srcData.size());
std::transform(std::begin(srcData), std::end(srcData), std::back_inserter(dstData),
[](std::wstring& guid) -> std::wstring { return std::move(guid); });
srcData.clear();
I am still new to lambdas and rvalue references, so initially I tried:
std::transform(std::begin(srcData), std::end(srcData),
std::back_inserter(dstData), &std::move<std::wstring>);
which doesn't work.
Do I have to put the move inside a lambda, or am I missing something obvious?
However, std::move must be used judiciously; using it blithely may lead to performance degradation, or simply be redundant, affecting readability of the code. Fortunately, the compiler can sometimes help with finding such wrong uses of std::move.
You have a lambda capture _theirStuff { std::move (theirStuff) }. This basically declares a member of the closure type, which will be initialized when the closure object is created as if it were in the lambda body.
And you would be moving _theirStuff into myStuff when the lambda is called. Note that, as a consequence, your lambda then cannot really be called twice. I mean, it can, but it will only really work once since _theirStuff will be empty after the first time the lambda is called…
An alternative is to use move iterators:
std::vector<std::wstring> dstData(std::make_move_iterator(srcData.begin()),
std::make_move_iterator(srcData.end()));
Or use the move
algorithm:
std::move(srcData.begin(), srcData.end(), std::back_inserter(dstData));
Since it was asked, here's how you could force the original proposal to work:
int main()
{
std::transform(std::begin(srcData),
std::end(srcData),
std::back_inserter(dstData),
static_cast<std::wstring&&(*)(std::wstring&)>(&std::move<std::wstring&>));
}
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