std::move 不适用于 RValue 参考函数

Kir*_*lak 1 c++ vector std rvalue-reference c++11

在尝试学习 std::move 和右值引用时,我刚刚遇到以下内容:

int _tmain(int argc, _TCHAR* argv[])
{
    std::vector<int> vecNumbers;
    vecNumbers.push_back(10);
    vecNumbers.push_back(20);

    foo(std::move(vecNumbers));

    std::cout<<"After Move \n";
    std::cout<<"size:"<<vecNumbers.size()<<"\n";

    return 0;
}

void foo(  std::vector<int> &&value)
{
    std::cout<<"size in Function:"<<value.size()<<"\n";
}
Run Code Online (Sandbox Code Playgroud)

输出

size in Function:2
After Move
size:2
Run Code Online (Sandbox Code Playgroud)

在调用向量上的移动后,我预计大小为 0 ,但这里它仅作为参考移动。有人可以解释一下这里发生了什么吗?

raf*_*x07 5

std::move仅转换为右值引用。

foo将 Rvalue ref 设为vector<int>。由move(vecNumbers)你得到vector<int>&&。在内部foo您只需访问vecNumbers中定义的内容即可main。您没有执行任何更改此向量内容的操作。

如果您确实想移动(窃取)内容,则vecNumbers必须调用移动构造函数或移动赋值运算符。在里面foo你可以这样做:

void foo(  std::vector<int>&& value)
{
    std::vector<int> v1{std::move(value)}; // invoke move ctor which steals content of value
    std::cout<<"size in Function:"<<value.size()<<"\n";
}
Run Code Online (Sandbox Code Playgroud)

或者您可以将 foo 的签名更改为:

void foo(std::vector<int> value) {

}
Run Code Online (Sandbox Code Playgroud)

然后当你打电话时

foo(std::move(vecNumbers))
Run Code Online (Sandbox Code Playgroud)

的 move 构造函数vector<T>被调用,它移动vecNumbersvalueinside foo