c – 为什么删除移动语义会导致std :: vector的问题?

参见英文答案 > What’s the exact semantics of a deleted function in C++11?2
做了一些研究后,我看到 C++11 has a defect与分配器需要类型是可移动/可复制的.我确信这是这个问题的原因,但是我对被删除和未声明的移动语义之间的行为感到困惑.

我有以下代码无法在MSVC12和Clang上编译:

#include <vector>

class copyable
{
public:
   copyable() = default;

   copyable(copyable const& other)
      : m_int(other.m_int)
   {}

   copyable& operator= (copyable const& other)
   {
      m_int = other.m_int;
      return *this;
   }

   copyable(copyable&&) = delete;
   copyable& operator= (copyable&&) = delete;

private:
   int m_int = 100;
};

int main()
{
   std::vector<copyable> objects;
   objects.push_back(copyable{});
}

这无法在MSVC上编译:

xmemory0(600): error C2280: ‘copyable::copyable(copyable &&)’ : attempting to reference a deleted function

和Cl(live sample):

new_allocator.h:120:23: error: call to deleted constructor of ‘copyable’

在这两种情况下,当我删除显式删除的移动构造/分配方法时,代码编译. AFAIK当你声明复制分配/构造方法时,编译器不会隐式声明相应的移动成员.所以他们还应该被有效地删除,对吧?为什么我删除显式删除移动构造/赋值时代码编译?

这个C11缺陷的一般解决方法是什么?我不希望我的对象是可移动的(但它们是可复制的).

解决方法

删除功能与不声明功能不同.

删除函数被声明并参与重载解析,但是如果您尝试调用它,就会产生错误.

如果您无法声明您的移动构造函数,编译器将不会在创建一个复制构造函数时创建一个.在rvalue上的重载分辨率会找到你的拷贝构造函数,这可能是你想要的.

你用foo(foo&&)= delete表示的是“如果有人试图移动构造这个对象,生成一个错误”.

我可以说明这里的区别:

void do_stuff( int  x ) { std::cout << x << "\n"; }
void do_stuff( double ) = delete;

void do_stuff2( int  x ) { std::cout << x << "\n"; }
//void do_stuff2( double ) = delete;

int main() {
  do_stuff(3); // works
  //do_stuff(3.14); // fails to compile
  do_stuff2(3); // works
  do_stuff2(3.14); // works,calls do_stuff2(int)
}

与上述问题的唯一部分,这使得这更令人困惑的是,特殊的成员函数自动创建或不基于略微奥术规则.

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...