我有一个名为explicitely删除的复制构造函数的类,让我们说NonCopyable
。然后是Base1
类,其成员类型为NonCopyable
。另一个以Base2
为父级的班级Base1
。最后 - 一个Derivative
类,父类为Base2
。
由于NonCopyable
不可复制,因此Base1
,Base2
和Derivative
也是不可复制的。但似乎已经删除了移动构造函数(和赋值运算符)。
在此测试:
以下行给出了这些错误:
Derived d1, d2 = std::move(d1);
GCC:' Derived :: Derived(Derived&&)'被隐式删除,因为默认定义不正确: class Derived:
其他错误只是声称Base1
和Base2
复制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);
}
答案 0 :(得分:7)
[class.copy] / 9 如果类
X
的定义没有显式声明移动构造函数,则当且仅当(9.4) -
X
没有用户声明的析构函数。
Base1
有一个用户声明的析构函数,因此没有移动构造函数。由于不可复制的成员,复制构造函数被隐式声明为已删除。因此Base1
既不会被复制也不会被移动,当然Base2
和Derived
也可以被复制。