我想将一个很大的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
的语义?
答案 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)。