使用 unique_ptr 时引用已删除的函数
Referencing deleted function when using unique_ptr
我有以下 class 定义:
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>
成员会在 InterpolatedSpreadConnector
复制构造函数上出现 attempting to reference deleted function
错误。奇怪的是,如果我用 shared_ptr
.
替换 unique_ptr
,错误就会消失
谁能解释为什么会这样?
要使此代码正常工作,在 C++17 之前,您需要为 class 定义一个 move-constructor。这可以很简单:
InterpolatedSpreadConnector(InterpolatedSpreadConnector &&) = default;
你的 user-defined 析构函数意味着 move-constructor 的隐式生成被抑制了。
并且没有 move-constructor,copy/move 操作回退到 copy-constructor,这导致编译错误,因为 implicitly-generated copy-constructor 被删除因为 unique_ptr
删除了 copy-constructor.
在 C++14 及更早版本中,auto x = X();
在概念上意味着我们创建一个临时 X
然后 copy/move 从临时构造 x
并销毁暂时的。允许编译器 elide 临时的,但该过程的正确构造函数必须仍然存在。
然而在 C++17 中,auto x = X();
将被定义为与 X x{};
相同的含义。
所以你的代码将在 C++17 中工作,尽管无论如何定义 move-constructor 是个好主意;或者最好删除析构函数定义(参见 Rule of zero)。
我有以下 class 定义:
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>
成员会在 InterpolatedSpreadConnector
复制构造函数上出现 attempting to reference deleted function
错误。奇怪的是,如果我用 shared_ptr
.
unique_ptr
,错误就会消失
谁能解释为什么会这样?
要使此代码正常工作,在 C++17 之前,您需要为 class 定义一个 move-constructor。这可以很简单:
InterpolatedSpreadConnector(InterpolatedSpreadConnector &&) = default;
你的 user-defined 析构函数意味着 move-constructor 的隐式生成被抑制了。
并且没有 move-constructor,copy/move 操作回退到 copy-constructor,这导致编译错误,因为 implicitly-generated copy-constructor 被删除因为 unique_ptr
删除了 copy-constructor.
在 C++14 及更早版本中,auto x = X();
在概念上意味着我们创建一个临时 X
然后 copy/move 从临时构造 x
并销毁暂时的。允许编译器 elide 临时的,但该过程的正确构造函数必须仍然存在。
然而在 C++17 中,auto x = X();
将被定义为与 X x{};
相同的含义。
所以你的代码将在 C++17 中工作,尽管无论如何定义 move-constructor 是个好主意;或者最好删除析构函数定义(参见 Rule of zero)。