从已移动捕获的 lambda 中重复移动变量



我有以下测试代码:

#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();
}

我得到的结果:

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

lambda 中移动已移动捕获的对象将始终具有它移动到 lambda 中的初始状态,或者这只是对象处于"有效但未指定状态"的工件,这是一个有效的假设?

std::move

执行移动操作;它只是将参数转换为右值。对于您的代码,printValue通过 rvalue-reference 获取参数,因此参数testValue将通过引用传递。但是移动操作不会对其执行,然后testValue不会更改。

如果将val更改为按值传递,则参数testValue将被移动到val中,或者您可以显式添加移动操作,例如

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

两者都会导致移动操作执行 3 次,然后你会得到不同的结果,例如使用 clang,

Got value: Test Value
Got value: 
Got value: 

PS:正如您所说,从对象中移动构造后,将保持有效但未指定的状态。尽管大多数实现都这样做,但标准不保证上述行为。

最新更新