在std :: move之后使用对象不会导致编译错误

Jub*_*eda 14 c++ compilation move-semantics c++11 stdmove

std::move对象上调用之后,如果在之后使用该对象,为什么语言不会导致编译错误?

是因为编译器无法检测到这种情况吗?

Mar*_*ica 9

C++语言设计的一般原则是"信任程序员".我可以想到的一些问题是拒绝任何对象的使用,因为它是一个参数std::move.

  • 确定给定用途是否在std::move一般情况下的呼叫之后是否等同于解决暂停问题.(换句话说,它无法完成.)你必须提出一些规则,用一种可以静态确定的方式来描述"后"的含义.
  • 通常,分配给作为参数的对象是完全安全的std::move.(一个特定的类可能会导致断言,但这将是一个非常奇怪的设计.)
  • 编译器很难判断给定函数是否只是分配类新值的元素.

  • 啊,很高兴知道[Rust已经解决了停机问题](http://typeinference.com/rust/2015/07/31/rust-ownership-part-i.html) (3认同)
  • @克里斯蒂安R 谢谢。因此,C++ 排除了 Rust 方法,因为“信任程序员”。 (2认同)

Jes*_*uhl 6

请记住,std::move只不过是对右值参考的强制转换.它本身实际上并没有移动任何东西.此外,该语言仅声明从对象移动的是有效/可破坏的状态,但除此之外没有说明其内容 - 它可能仍然是完整的,它可能不是或(就像std::unique_ptr它可能被定义为具有具体内容(nullptr)) - 这一切都取决于移动构造函数/ move-assignment-operator实现的内容.

因此,访问移动对象是否安全/有效完全取决于特定对象.std::unique_ptr在移动之后阅读,看看它nullptr是否完美无缺 - 例如 - 对于其他类型; 没那么多.


fis*_*000 1

对象\xe2\x80\x99s 移动后状态的性质由实现者定义;在某些情况下,移动对象可能会使其处于完全可用的状态,而在其他情况下,对象可能会变得无用(或者更糟,使用起来有些危险)。

\n\n

虽然我有点同意 \xe2\x80\x93 ,但如果能够选择生成警告,那就太好了,至少,如果在移动后以潜在危险的方式使用对象,我不知道 \xe2\x80\x99t GCC 或 Clang 的选项可引起人们对此类代码气味的注意。

\n\n

(事实上​​,对于勇敢者来说,这可能为Clang 插件等奠定良好的基础奠定良好的基础!)

\n

  • @RichardCritten,从技术意义上讲,这是正确的 w/r/t `std::move(…)` 的作用 - 但它允许实现者编写一个移动构造函数(和/或一个移动赋值运算符),它实际上是这样做的操纵对象的状态。 (2认同)