鉴于我有一个前向声明的类型:
class Foo;
我想对这种类型进行unique_ptr
:
unique_ptr<Foo> pFoo;
这在visual-studio-2017中工作正常,但我无法让它在visual-studio-2012中工作。
C:\Program Files (x86(\Microsoft Visual Studio 11.0\VC\include\memory(1150(:错误 C2027:使用未定义的类型
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
]
编译std::default_delete<_Ty>
类模板实例化的参考C:\Program Files (x86(\Microsoft Visual Studio 11.0\VC\include\memory(1281(:请参阅对类模板实例化的引用,std::is_empty<_Ty>
编译时使用 [ _Ty=
std::d efault_delete ] O:\
Engine\
stetestbed\include\STETestbed\ComponentDirector.h(63( :请参阅
使用
[
_Ty=Foo
] 编译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
声明
在黑暗时代是否有解决方法,或者我可以不转发声明吗?
正如Jarod42所提到的,问题似乎是可视化工作室-2012实现的default_deleter
需要声明的完整类型。更高版本的 visual-studio 只需要在调用括号运算符时使用完整类型。
我们可以通过提供一个函子来解决这个问题,该函子提供了一个不需要声明完整类型的删除器:
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>))