不合理地删除了移动构造函数

时间:2017-03-04 12:32:17

标签: c++ c++11 inheritance move-semantics

我有一个名为explicitely删除的复制构造函数的类,让我们说NonCopyable。然后是Base1类,其成员类型为NonCopyable。另一个以Base2为父级的班级Base1。最后 - 一个Derivative类,父类为Base2

由于NonCopyable不可复制,因此Base1Base2Derivative也是不可复制的。但似乎已经删除了移动构造函数(和赋值运算符)。

在此测试:

以下行给出了这些错误:
Derived d1, d2 = std::move(d1);

  

GCC:' Derived :: Derived(Derived&&)'被隐式删除,因为默认定义不正确:      class Derived:
  其他错误只是声称Base1Base2复制ctors被隐式删除,这并不奇怪

     

MSVC:错误C2280:' Derived :: Derived(const Derived&)':尝试引用已删除的函数

在提供的链接中,还有注释行,这些行给出了类似的错误。请取消注释以查看我想向您显示的更多错误(例如,remove_if取消注释,它会抱怨删除的移动(在GCC上) / copy (在MSVC上) 指定运营商)。
我想要实现的是使Derivative(及其基础)可移动,但不可复制。

我正在使用Visual Studio 2015并获得与我提供的msvc链接完全相同的错误,但我不确定在 rextester.com上使用哪个版本的MSVC进行编译

我也应@Richard Critten的请求粘贴代码:

    class NonCopyable
    {
    public:
       NonCopyable() { }
       NonCopyable(const NonCopyable &) = delete;
       NonCopyable & operator=(const NonCopyable &) = delete;
       NonCopyable(NonCopyable &&) { }
       NonCopyable & operator=(NonCopyable &&) { return *this; }
    };

     class Base1
     {
     public:
          virtual ~Base1() = default;

     private:
          NonCopyable m;
     };

     class Base2 :
        public Base1
     {
     public:
          virtual ~Base2() = default;
     };

     class Derived :
        public Base2
     {
     };



int main()
{
    std::vector<Derived> v;
    //std::remove_if(v.begin(), v.end(), [](const Derived &) { return true; });
    //v.emplace_back();
    Derived d1, d2 = std::move(d1);
}

1 个答案:

答案 0 :(得分:7)

  

[class.copy] / 9 如果类X的定义没有显式声明移动构造函数,则当且仅当      

(9.4) - X没有用户声明的析构函数。

Base1有一个用户声明的析构函数,因此没有移动构造函数。由于不可复制的成员,复制构造函数被隐式声明为已删除。因此Base1既不会被复制也不会被移动,当然Base2Derived也可以被复制。