[英]Workaround for Making a unique_ptr to a Forward Declared Type
Given that I have a forward declared type: 鉴于我有一个前向声明的类型:
class Foo;
I want to make a unique_ptr
to this type: 我想为此类型创建一个
unique_ptr
:
unique_ptr<Foo> pFoo;
This works fine in visual-studio-2017 but I can't make it work in visual-studio-2012 . 这在visual-studio-2017中工作正常,但我无法在visual-studio-2012中工作 。
C:\\Program Files (x86)\\Microsoft Visual Studio 11.0\\VC\\include\\memory(1150): error C2027: use of undefined type
Foo
(....\\src\\STETestbed\\STETestbed.cpp)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) : see declaration ofFoo
O:\\ Engine \\ stetestbed \\ include \\ STETestbed \\ ComponentDirector.h(26):参见
Foo
声明
C:\\Program Files (x86)\\Microsoft Visual Studio 11.0\\VC\\include\\memory(1149) : while compiling class template member functionvoid std::default_delete<_Ty>::operator ()(_Ty *) throw() const
C:\\ Program Files(x86)\\ Microsoft Visual Studio 11.0 \\ VC \\ include \\ memory(1149):编译类模板成员函数时
void std::default_delete<_Ty>::operator ()(_Ty *) throw() const
with与
[[
_Ty=Foo_Ty = Foo
]]
C:\\Program Files (x86)\\Microsoft Visual Studio 11.0\\VC\\include\\memory(1444) : see reference to function template instantiationvoid std::default_delete<_Ty>::operator ()(_Ty *) throw() const
being compiledC:\\ Program Files(x86)\\ Microsoft Visual Studio 11.0 \\ VC \\ include \\ memory(1444):请参见对函数模板实例化的引用
void std::default_delete<_Ty>::operator ()(_Ty *) throw() const
正在编译
with与
[[
_Ty=Foo_Ty = Foo
]]
C:\\Program Files (x86)\\Microsoft Visual Studio 11.0\\VC\\include\\type_traits(743) : see reference to class template instantiationstd::default_delete<_Ty>
being compiledC:\\ Program Files(x86)\\ Microsoft Visual Studio 11.0 \\ VC \\ include \\ type_traits(743):请参见对正在编译的类模板实例化
std::default_delete<_Ty>
引用
with与
[[
_Ty=Foo_Ty = Foo
]]
C:\\Program Files (x86)\\Microsoft Visual Studio 11.0\\VC\\include\\memory(1281) : see reference to class template instantiationstd::is_empty<_Ty>
being compiledC:\\ Program Files(x86)\\ Microsoft Visual Studio 11.0 \\ VC \\ include \\ memory(1281):请参见对正在编译的类模板实例化
std::is_empty<_Ty>
引用
with与
[[
_Ty=std::default_delete_Ty = std :: default_delete
]]
O:\\Engine\\stetestbed\\include\\STETestbed\\ComponentDirector.h(63) : see reference to class template instantiationstd::unique_ptr<_Ty>
being compiledO:\\ Engine \\ stetestbed \\ include \\ STETestbed \\ ComponentDirector.h(63):请参见对正在编译的类模板实例化
std::unique_ptr<_Ty>
引用
with与
[[
_Ty=Foo_Ty = Foo
]]
C:\\Program Files (x86)\\Microsoft Visual Studio 11.0\\VC\\include\\memory(1151): error C2338: can't delete an incomplete type (....\\src\\STETestbed\\STETestbed.cpp)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): warning C4150: deletion of pointer to incomplete typeFoo
;C:\\ Program Files(x86)\\ Microsoft Visual Studio 11.0 \\ VC \\ include \\ memory(1152):警告C4150:删除了指向不完整类型
Foo
的指针; no destructor called (....\\src\\STETestbed\\STETestbed.cpp)没有调用的析构函数(.... \\ src \\ STETestbed \\ STETestbed.cpp)
O:\\Engine\\stetestbed\\include\\STETestbed\\ComponentDirector.h(26) : see declaration ofFoo
O:\\ Engine \\ stetestbed \\ include \\ STETestbed \\ ComponentDirector.h(26):参见
Foo
声明
Was there a workaround for that back in the dark ages, or can I just not forward declare? 在黑暗时代是否有针对性的解决方法,还是我只能不向前声明?
As mentioned by Jarod42 The problem seems to be that the default_deleter
implemented by visual-studio-2012 required a complete type on declaration. 如Jarod42所述 ,问题似乎在于visual-studio-2012实现的
default_deleter
需要声明时使用完整的类型。 Latter versions of visual-studio only required the complete type at the point the parenthesis operator is called. Visual Studio的最新版本仅在调用括号运算符时需要完整的类型。
We can work around this by providing a functor which provides a deleter which does not require the complete type on declaration: 我们可以通过提供一个仿函数来解决此问题,该仿函数提供一个不需要在声明时使用完整类型的删除器:
template <typename T>
void custom_deleter(T* param) {
delete param;
}
To use custom_deleter
as a template parameter we'll need to make it into a functor otherwise the compiler will error: 要将
custom_deleter
用作模板参数,我们需要将其设置为函子,否则编译器将出错:
error C2207:
std::_Unique_ptr_base<_Ty,_Dx,_Empty_deleter>::_Mydel
: a member of a class template cannot acquire a function type错误C2207:
std::_Unique_ptr_base<_Ty,_Dx,_Empty_deleter>::_Mydel
:类模板的成员无法获取函数类型
So in the header where Foo
is forward declared we'll need to define the unique_ptr
as: 因此,在向前声明
Foo
的标头中,我们需要将unique_ptr
定义为:
unique_ptr<Foo, function<void(Foo*)>> pFoo
And in the implementation file where Foo
is defined we'll need to assign it as: 在定义
Foo
的实现文件中,我们需要将其分配为:
pFoo = decltype(pFoo)(new Foo, std::function<void(Foo*)>(custom_deleter<Foo>))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.