我正在编写一些测试用例,注意到一种奇怪的行为。
对字符串的移动分配没有删除第一个字符串的值,而是分配了目标字符串的值。
示例代码:
#include <utility>
#include <string>
#include <iostream>
int main(void) {
std::string a = "foo";
std::string b = "bar";
std::cout << a << std::endl;
b = std::move(a);
std::cout << a << std::endl;
return 0;
}
结果:
$ ./string.exe
foo
bar
预期结果:
$ ./string.exe
foo
所以我的问题:
环境: Win10 64bit msys2 g ++ 5.2
修改
在阅读了@OMGtechy可能的重复答案和答案之后 我扩展了测试以检查小字符串优化。
#include <utility>
#include <string>
#include <iostream>
#include <cinttypes>
#include <sstream>
int main(void) {
std::ostringstream oss1;
oss1 << "foo ";
std::ostringstream oss2;
oss2 << "bar ";
for (std::uint64_t i(0);;++i) {
oss1 << i % 10;
oss2 << i % 10;
std::string a = oss1.str();
std::string b = oss2.str();
b = std::move(a);
if (a.size() < i) {
std::cout << "move operation origin was cleared at: " << i << std::endl;
break;
}
if (0 == i % 1000)
std::cout << i << std::endl;
}
return 0;
}
这在我的机器上运行高达1 MB,这不再是一个小字符串了。 它刚刚停止,所以我可以在这里粘贴源(阅读:我停止了它)。
答案 0 :(得分:0)
这可能是由于短字符串优化;即没有内部指针指向&#34;移动&#34;结束了,所以它最终就像一个副本一样。
我建议您尝试使用大量字符串;这应该足以绕过短字符串优化并展示您期望的行为。
这是完全有效的,因为C ++标准声明从对象移动(有一些例外,字符串不是C ++ 11中的其中一个)应处于有效但未指定的状态。