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

Repeatedly moving a variable from lambda that has been move captured

我有以下测试代码:

#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 中的初始状态是一个有效的假设,或者这只是一个对象在 "valid but unspecified state"?

std::move不执行移动操作;它只是将参数转换为右值。对于您的代码,printValue 通过右值引用获取参数,因此参数 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:如您所说,从对象移动构造后,对象将处于有效但未指定的状态。尽管大多数实现都这样做,但标准不保证上述行为。