从std::stringstream返回字符串时是否需要使用std::move?
std::ostringstream::str() 移动语义的使用疑问解答
直接说结论
要触发str()&&的无拷贝移动语义,必须把ss转换成右值——也就是用std::move(ss).str()这种写法。直接调用ss.str()只会走左值版本,必然会复制字符串。
逐个分析你给出的三种返回写法
1. return std::move(ss.str());
完全没必要这么写。ss.str()调用的是左值版本,已经复制出一个临时std::string(本身就是右值),对临时对象再套std::move()纯属画蛇添足——返回时临时对象本来就会自动触发移动构造,甚至可能被编译器优化掉。但最关键的问题是,这一步已经做了字符串复制,性能损耗已经产生了,move只是转移复制后的临时对象,没解决根本问题。
2. return ss.str();
这会调用str()的左值重载,强制复制流内部的大字符串,返回一个新的std::string。虽然返回时这个临时字符串会被移动到f()的返回值,但最耗时的复制步骤已经完成了,完全达不到你想要的无拷贝效果。
3. return std::move(ss).str();
这才是正确的写法:
std::move(ss)把左值的ss转成右值引用,此时调用的是str()&&重载版本- 这个版本会直接把流内部的字符串资源“挪”到返回值里,不会做任何字符串复制,完美节省大字符串拷贝的性能开销
- 返回的临时字符串会自动移动到
main()的x里,不需要额外加std::move()
额外补充
C++11及以后的标准库中,std::basic_stringstream的str()确实提供了右值重载,专门用来转移内部字符串的所有权,就是为了避免大字符串复制的性能问题。你用的标准库实现支持这个特性,那只要写法正确就能享受到优化。
内容的提问来源于stack exchange,提问作者Lasersköld
相关产品推荐
相关产品推荐

