为什么要“移动语义”而不是简单的“ mcpy”?

B S*_*son 4 c++ c++11 c++17

给出以下代码:

typename std::aligned_storage<sizeof(T), alignof(T)>::type storage_t;

//this moves the back of src to the back of dst:
void push_popped(std::list<storage_t> & dstLst, std::list<storage_t> & srcLst)
{
  auto & src = srcLst.back();
  dstLst.push_back(storage_t());
  auto & dst = dstLst.back();
  std::memcpy(&dst, &src, sizeof(T));
  srcLst.pop_back();
}
Run Code Online (Sandbox Code Playgroud)

我知道这种方法通常不正确的3个原因(即使该方法避免了调用src->~T(),因此也避免了T对资源的重复声明)。

  1. U*指向U同一对象的其他成员的类型的对象成员
  2. 隐藏的类成员可能需要更新(例如,vtable)
  3. 系统需要记录不再T存在,src并且T现在确实存在dst

(这里提到了这些:http : //www.gamedev.net/topic/655730-c-stdmove-vs-stdmemcpy/#entry5148523。)

假设该T类型不是其内存地址为其状态(例如,std::mutexstd::condition_variable)的属性,那么这种方法是否仅有这些问题?还是还有其他可能出错的事情?我想对未知问题进行描述。

我想认为我开发了“对象重定位语义”,但是我不希望人们考虑其中是否有明显的漏洞。

Yak*_*ont 5

“平凡可复制”的概念意味着memcpy是安全的。您可以通过中的特征来测试类型是否可微复制std

它包含了销毁它的想法。在您的情况下,您希望销毁不是闲事,而是要在源头上而不是在目标上进行。

已在C ++ 1z标准化过程中提出了“移动并销毁源代码”的概念,而与“普通可复制”的概念无关。出于异常安全的考虑提出了该建议。在某些类型中,move-construct不是异常安全的,但是move-construct-and-destroy-source会是异常安全的。还有涉及异常和容器分配的各种问题,这使得noexcept move-ctor操作非常有价值。

如果这成为标准,那么如果证明它很有价值,那么如果您不破坏源代码的话,也可以添加一个简单可复制的概念。

它并不适用于所有可以增强语义的移动,并且可能需要程序员的努力(编译器如何得出“淘汰驱逐舰可以”不是一件容易的事;所有这些都是不重要的)图灵机行为的非结构性很棘手。)