为什么删除移动语义导致std :: vector的问题? [英] Why do deleted move semantics cause problems with std::vector?

查看:257
本文介绍了为什么删除移动语义导致std :: vector的问题?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

进行一些调查后,我发现 C ++ 11具有缺陷,其具有需要该类型是可移动/可复制的分配器。我确信这是这个问题的原因,但我困惑的删除和未声明移动语义之间的行为。

After doing a bit of research, I see that C++11 has a defect with allocators that require the type to be movable/copyable. I'm sure that this is the cause of this problem, however I am confused about the behavior between deleted and not declared move semantics.

我有以下代码失败在MSVC12和Clang上编译:

I have the following code which fails to compile on both MSVC12 and 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上编译:

This fails to compile on MSVC with:


xmemory0(600):error C2280:'Copyable :: Copyable(可复制&&)':试图引用已删除的函数

xmemory0(600): error C2280: 'Copyable::Copyable(Copyable &&)' : attempting to reference a deleted function

并在Clang(即时取样):


new_allocator.h:120:23:错误:调用'Copyable'的已删除构造函数

new_allocator.h:120:23: error: call to deleted constructor of 'Copyable'

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

In both cases, when I remove the explicitly deleted move construct/assign methods, the code compiles. AFAIK when you declare copy assign/construct methods, the compiler does not implicitly declare the corresponding move members. So they should still be effectively deleted, right? Why does the code compile when I remove the explicit deletion of move construct/assign?

对于这个C ++ 11缺陷,一般是什么好的解决方法?我不希望我的对象是可移动的(但它们是可复制的)。

What is a good workaround for this C++11 defect in general? I do not want my objects to be movable (but they are copyable).

推荐答案

删除函数与不是

已删除的函数已声明并参与重载解析,但如果尝试调用它,则会产生错误。

A deleted function is declared and participates in overload resolution, but if you attempt to call it an error is produced.

如果你没有声明你的移动构造函数,编译器不会创建一个,因为你创建了一个复制构造函数。

If you fail to declare your move constructor, the compiler will not create one as you created a copy constructor. Overload resolution on an rvalue will find your copy constructor, which is probably what you want.

你用 foo(foo&& )= delete 是如果任何人尝试移动构造此对象,生成错误。

What you said with your foo(foo&&)=delete was "if anyone tries to move construct this object, generate an error".

我可以说明这里的区别: p>

I can illustrate the difference here:

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)
}

这使得这有点更混乱是特殊成员函数是自动创建或不基于略微奥秘的规则。

the only part with your above problem that makes this a bit more confusing is that special member functions are automatically created or not based off slightly arcane rules.

这篇关于为什么删除移动语义导致std :: vector的问题?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆