理解std :: array的移动语义

Jav*_*i V 3 c++ move-semantics c++11

我试图理解移动语义,所以我做了以下测试:

#include <iostream>
#include <array>

using namespace std;

void tryToMove(array<double,3> && v) {
    array<double,3> v_ = std::move(v);
    std::cout << v_[0] << "  " << v_[1] << "  " << v_[2] <<'\n';
}

int main () {
    array<double,3> v{1,2,3};

    tryToMove(std::move(v));
    std::cout << v[0] << "  " << v[1] << "  " << v[2] <<'\n';
}
Run Code Online (Sandbox Code Playgroud)

std::cout因为v_应该被移入,所以我期待主要的sementation错误tryToMove.但是,输出是:

1 2 3
1 2 3
Run Code Online (Sandbox Code Playgroud)

这里到底发生了什么?

谢谢!

Jon*_*ely 15

我期待着一个脓毒症的错误

首先,获取段错误的大多数方法都是由于未定义的行为,在这种情况下,任何事情都可能发生,您可能不应该期待任何具体的事情.

因为v_应该被移动

A std::array包含直接嵌入其中的元素(不在堆上,由指针引用,如同std::vector),因此您无法将其内容移动到任何位置.他们永远都在里面.

所以你所做的就是从旧的数组中初始化一个新数组,你没有移动任何东西.新数组的元素将由rvalue双精度初始化,但这也不会移动任何东西,因为你不能"移动"一个double(它没有外部分配的数据来传输).所以它只是每个元素的副本.

  • @JaviV如果你想学习我不会认为它是微妙的. (3认同)
  • 如果我有一个来自`std :: vector`的移动,没有什么可以阻止我调用`clear()`并重用它,例如.经验法则是"不做任何有先决条件的事情,不检查先决条件".除了分配和销毁之外,没有什么比这更难了. (3认同)
  • @chris,我不同意这个经验法则,它比必要的要保守得多. (2认同)