C++ 不合理地删除移动构造函数
我有一个类,它的复制构造函数被明确删除,命名为,C++ 不合理地删除移动构造函数,c++,c++11,inheritance,move-semantics,C++,C++11,Inheritance,Move Semantics,我有一个类,它的复制构造函数被明确删除,命名为,NonCopyable。然后有一个类Base1,其成员类型为NonCopyable。另一类Base2以Base1为父类。最后是一个派生类,父类是Base2 由于NonCopyable是不可复制的,很明显Base1、Base2和派生也是不可复制的。但似乎移动构造函数(和赋值操作符)也被删除了 在这里测试它: 下面一行给出了这些错误: 派生d1,d2=std::move(d1) GCC:“派生::派生(派生&&)”被隐式删除,因为默认定义的格式
NonCopyable
。然后有一个类Base1
,其成员类型为NonCopyable
。另一类Base2
以Base1
为父类。最后是一个派生类,父类是Base2
由于NonCopyable
是不可复制的,很明显Base1
、Base2
和派生
也是不可复制的。但似乎移动构造函数(和赋值操作符)也被删除了
在这里测试它:
派生d1,d2=std::move(d1)代码>
GCC:“派生::派生(派生&&)”被隐式删除,因为默认定义的格式不正确:
派生类:
其余的错误只是声称Base1
和Base2
复制因子被隐式删除,这并不奇怪
MSVC:错误C2280:'Derived::Derived(const-Derived&'):试图引用已删除的函数
在提供的链接中也有注释行,给出了类似的错误。请取消注释,以查看我想向您展示的更多错误(例如,如果未注释,则使用remove\u),它会抱怨删除的移动(在GCC上)/复制(在MSVC上)分配运算符)。
我想实现的是使衍生工具(及其基础)可移动,但不可复制
我正在使用Visual Studio 2015,得到的错误与我提供的msvc链接中的错误完全相同,但我不确定在rextester.com上编译msvc的版本
我也是应@Richard Criten的请求在这里粘贴代码的:
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);
}
类不可复制
{
公众:
不可复制(){}
不可复制(const NonCopyable&)=删除;
NonCopyable&运算符=(const NonCopyable&)=delete;
不可复制(不可复制&&{}
NonCopyable&运算符=(NonCopyable&&){return*this;}
};
基类1
{
公众:
virtual~Base1()=默认值;
私人:
不可复制m;
};
类别2:
公共基地1
{
公众:
virtual~Base2()=默认值;
};
派生类:
公共基地2
{
};
int main()
{
std::向量v;
//std::remove_if(v.begin(),v.end(),[](常量派生&){return true;});
//v、 安置你回来();
导出的d1,d2=std::move(d1);
}
[class.copy]/9如果类X
的定义没有显式声明移动构造函数,则当且仅当
(9.4)
X
没有用户声明的析构函数
Base1
有一个用户声明的析构函数,因此它没有移动构造函数。由于不可复制的成员,复制构造函数被隐式声明为已删除。因此Base1
既不能复制也不能移动,当然Base2
和派生的
也不能与之一起移动
[class.copy]/9如果类X
的定义没有显式声明移动构造函数,则当且仅当
(9.4)X没有用户声明的析构函数
Base1
有一个用户声明的析构函数,因此它没有移动构造函数。由于不可复制的成员,复制构造函数被隐式声明为已删除。所以Base1
既不能复制也不能移动,当然Base2
和Derived
也不能与它一起复制和移动。你能在这里显示代码吗?我对随机链接过敏。另外,如果这个问题被证明是有用的,那么这里的代码更适合搜索,我们不必担心它会从链接的网站上被删除。请。@Someprogrammerdude我认为派生的
不符合这些条件。但是如果你看到我的错误,请告诉我它在哪里。@cris:一些实验表明,Base
和Base2
都有必要声明它们的移动构造函数,但是派生的
可以使用默认值。我不知道确切的原因。问题可能是;其余的都是不必要的并发症。未生成Base1
的移动构造函数,因为它有一个用户声明的析构函数。你能在这里显示代码吗?我对随机链接过敏。另外,如果这个问题被证明是有用的,那么这里的代码更适合搜索,我们不必担心它会从链接的网站上被删除。请。@Someprogrammerdude我认为派生的
不符合这些条件。但是如果你看到我的错误,请告诉我它在哪里。@cris:一些实验表明,Base
和Base2
都有必要声明它们的移动构造函数,但是派生的
可以使用默认值。我不知道确切的原因。问题可能是;剩下的是不必要的复杂情况。未生成Base1
的移动构造函数,因为它具有用户声明的析构函数.Huh。它起作用了!但是无论如何,我必须有Base1
和Base2
析构函数。所以唯一的选择是显式定义移动构造函数?另外-你能提供一个链接到你从哪里获得报价吗?你可以显式地将它们定义为默认值。然后还需要显式定义默认构造函数。引用自C++14标准草案:现在我终于记住了。这是斯科特·迈尔斯在做的。他注意到默认情况下,从一个类不变的类中移动(用一个用户定义的析构函数来表示),并在COMP.ST.C++和COMP.Lang.C++中发布了它。进行了一些讨论,修改了提议的规则。它起作用了!但是我必须有Base1
和B