std :: move of*this以及稍后访问类方法和字段

fed*_*ino 3 c++ move-semantics c++11

我理解这对代码来说是愚蠢的...但为了理解,请考虑以下事项:

#include <iostream>
#include <memory>
#include <utility>

struct S;
void f( S && s );

struct S {
  S() : i{std::vector<int>(10, 42)} {}
  std::vector<int> i;
  void call_f() { f( std::move(*this) ); }
  void read() { std::cout << " from S: " <<  i.at(3) << std::endl; }
};

void f(S && s)  { std::cout << " from f: " <<  s.i.at(3) << std::endl; }

int main() {
  S s;
  s.call_f();
  s.read();
}
Run Code Online (Sandbox Code Playgroud)

这为g ++和clang ++编译和运行,而我希望它std::vector<int>会被移动.在gdb中运行并查看内存显示,地址后s.i未设置为零std::move,而我预计非POD类型的地址.因此,我期望从这段代码中出现段错误.
可以请任何人解释我这种行为吗?为什么既没有s也没有内部领域失效?这是一个特色this吗?

Tar*_*ama 5

std::move实际上并没有移动任何东西,它只是投射到一个左值以允许移动(有点用词不当,但是,嘿,我们现在坚持它).

如果你要做一个实际的移动构造,你很可能会看到边界检查的异常std::vector::at.

void f(S && s) { 
    S steal = std::move(s);
    std::cout << " from f: " <<  s.i.at(3) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

GCC 6.1给了我这个

terminate called after throwing an instance of 'std::out_of_range'
  what():  vector::_M_range_check: __n (which is 3) >= this->size() (which is 0)
bash: line 7: 18043 Aborted                 (core dumped) ./a.out
Run Code Online (Sandbox Code Playgroud)

  • @LightnessRacesinOrbit一旦处理了最初的惊喜,我很高兴它没有被命名为`std :: enable_moving`. (3认同)
  • @Quentin为什么不`std :: give_me_something_I_can_move_just_in_case`? (2认同)