将std :: string移动到函数param

时间:2019-03-21 12:54:23

标签: c++ rvalue-reference

我想将一个很大的std :: string移到类的成员上。

这是我的代码:

#include <cassert>
#include <string>
#include <iostream>
using namespace std;

class SomeClass {
public:
    void some_method(std::string&& str) {
        my_str = str;
    }

    std::string my_str;
};

int main() {
    SomeClass some_class;

    std::string large_str(100000, 'a');

    some_class.some_method(std::move(large_str));

    assert(large_str.empty());
    assert(!some_class.my_str.empty());
    return 0;
}

移动后,我希望large_str为空,但是此代码断言在行assert(large_str.empty())上失败。

我是否误解了std::move的语义?

1 个答案:

答案 0 :(得分:6)

  

我是否误解了std::move的语义?

部分是。您忘记将函数参数str强制转换为右值。在some_method中,它再次成为左值。要解决此问题:

void some_method(std::string&& str) {
    my_str = std::move(str);
    //       ^^^^^^^^^ Necessary: invoke std::move a 2nd time
}

但是请注意以下几点。 “移出的” std::string对象应该是assert上没有的对象。从here开始,过载#8(强调我的):

  

移动构造函数。使用move语义构造包含其他内容的字符串。其他则保持有效,但未指定状态

您不希望您的程序依赖于未指定的状态(即使碰巧某个特定的实现使std::string::size在消耗其资源后返回0)。