我有以下类定义:
class InterpolatedSpreadConnector
{
public:
~InterpolatedSpreadConnector() = default;
GPUImage* operator()() override;
GPUImage* AncestorReducedConnectivity = nullptr;
GPUImage* OffspringReducedConnectivity = nullptr;
};
,在声明auto connector = InterpolatedSpreadConnector();
中使用时效果很好。我想将这些原始指针更改为unique_ptr
s。
包含memory
并在定义中使用std::unique_ptr<GPUImage>
成员替换原始指针会在attempting to reference deleted function
副本构造函数上出现InterpolatedSpreadConnector
错误。奇怪的是,如果我用unique_ptr
替换shared_ptr
,那么错误就会消失。
有人可以解释为什么会这样吗?
答案 0 :(得分:4)
要使这段代码有效,在C ++ 17之前,你需要为你的类定义一个move-constructor。这可以很简单:
InterpolatedSpreadConnector(InterpolatedSpreadConnector &&) = default;
用户定义的析构函数意味着隐式生成移动构造函数被抑制。
如果没有move-constructor,复制/移动操作会回退到copy-constructor,这会导致编译错误,因为隐式生成的复制构造函数被删除,因为unique_ptr
有一个已删除的复制构造函数
在C ++ 14及更早版本中,auto x = X();
在概念上意味着我们创建一个临时X
,然后从临时文件中复制/移动构造x
并销毁临时文件。允许编译器临时elide,但该过程的正确构造函数必须仍然存在。
但是在C ++ 17中,auto x = X();
将被定义为与X x{};
相同。
所以你的代码将在C ++ 17中运行,尽管最好定义move-constructor;或者最好删除析构函数定义(参见Rule of zero)。