字符串移动赋值交换值

时间:2016-04-05 09:39:57

标签: c++ c++11 g++

我正在编写一些测试用例,注意到一种奇怪的行为。

对字符串的移动分配没有删除第一个字符串的值,而是分配了目标字符串的值。

示例代码:

#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

所以我的问题:

  • 这是故意的吗?
  • 这是否只发生在字符串和/或STL对象上?
  • 自定义对象是否会发生这种情况(如用户定义的那样)?

环境: 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,这不再是一个小字符串了。 它刚刚停止,所以我可以在这里粘贴源(阅读:我停止了它)。

1 个答案:

答案 0 :(得分:0)

这可能是由于短字符串优化;即没有内部指针指向&#34;移动&#34;结束了,所以它最终就像一个副本一样。

我建议您尝试使用大量字符串;这应该足以绕过短字符串优化并展示您期望的行为。

这是完全有效的,因为C ++标准声明从对象移动(有一些例外,字符串不是C ++ 11中的其中一个)应处于有效但未指定的状态。