首页 > 解决方案 > 将 unique_ptr 设置为前向声明类型的解决方法

问题描述

鉴于我有一个前向声明的类型:

class Foo;

我想对unique_ptr这种类型做一个:

unique_ptr<Foo> pFoo;

这在中运行良好,但我无法使其在中运行。

C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\memory(1150): error C2027: use of undefined type Foo(....\src\STETestbed\STETestbed.cpp)
O:\Engine\stetestbed \include\STETestbed\ComponentDirector.h(26) :参见Foo
C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\memory(1149) 的声明:void std::default_delete<_Ty>::operator ()(_Ty *) throw() const
使用
[
_Ty=Foo
]编译类模板成员函数时
C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\memory(1444) :参见 使用 [ _Ty=Foo ]void std::default_delete<_Ty>::operator ()(_Ty *) throw() const编译的函数模板实例化的参考




C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\type_traits(743) :请参阅使用 [ _Ty=Foo ] C:\Program Files (x86)\Microsoft Visual Studio 11.0std::default_delete<_Ty>编译的 类模板实例化的参考\VC\include\memory(1281) : 参见 使用 [ _Ty=std::default_delete ]编译的类模板实例化的参考 O:\Engine\stetestbed\include\STETestbed\ComponentDirector.h(63) : 参见类模板的参考 使用 [ _Ty=Foo ]编译的实例化




std::is_empty<_Ty>




std::unique_ptr<_Ty>




C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\memory(1151): 错误 C2338: 无法删除不完整的类型 (....\src\STETestbed\STETestbed.cpp)
C:\ Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\memory(1152):警告 C4150:删除指向不完整类型的指针Foo;没有调用析构函数 (....\src\STETestbed\STETestbed.cpp)
O:\Engine\stetestbed\include\STETestbed\ComponentDirector.h(26) :见声明Foo

在黑暗时代是否有解决方法,或者我可以不转发声明?

标签: c++visual-studio-2012smart-pointersunique-ptrforward-declaration

解决方案


正如 Jarod42 所提到的,问题似乎是default_deleter在声明时需要一个完整的类型。后期版本的只需要调用括号运算符时的完整类型。

我们可以通过提供一个函子来解决这个问题,该函子提供了一个不需要声明完整类型的删除器:

template <typename T>
void custom_deleter(T* param) {
    delete param;
}

custom_deleter用作模板参数,我们需要将其转换为仿函数,否则编译器会出错:

错误 C2207: std::_Unique_ptr_base<_Ty,_Dx,_Empty_deleter>::_Mydel: 类模板的成员无法获取函数类型

因此,在前向声明的标题中,Foo我们需要将其定义unique_ptr为:

unique_ptr<Foo, function<void(Foo*)>> pFoo

在定义的实现文件中,Foo我们需要将其分配为:

pFoo = decltype(pFoo)(new Foo, std::function<void(Foo*)>(custom_deleter<Foo>))

推荐阅读