Ela*_*782 2 c++ opencv smart-pointers unique-ptr c++11
我试图在智能指针中包装OpenCV(CvPOSITObject)的C-API中的对象.根据我的理解,它应该类似于以下内容:
unique_ptr<CvPOSITObject, decltype(cvReleasePOSITObject)> positObject;
positObject = unique_ptr<CvPOSITObject, decltype(cvReleasePOSITObject)>(cvCreatePOSITObject(param1, param2), cvReleasePOSITObject);
Run Code Online (Sandbox Code Playgroud)
但是我收到编译器错误,谷歌并没有真正帮助.
这两个函数的声明是:
CVAPI(CvPOSITObject*) cvCreatePOSITObject( CvPoint3D32f* points, int point_count );
CVAPI(void) cvReleasePOSITObject( CvPOSITObject** posit_object );
Run Code Online (Sandbox Code Playgroud)
我得到类似的东西
1>C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\memory(1227): error C2207: 'std::_Unique_ptr_base<_Ty,_Dx,_Empty_deleter>::_Mydel' : a member of a class template cannot acquire a function type
1>C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\memory(1322): warning C4180: qualifier applied to function type has no meaning; ignored
1> Myfile.cpp
1>C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\memory(1221): warning C4180: qualifier applied to function type has no meaning; ignored
1> C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\memory(1283) : see reference to class template instantiation 'std::_Unique_ptr_base<_Ty,_Dx,_Empty_deleter>' being compiled
1> with
1> [
1> _Ty=CvPOSITObject,
1> _Dx=void (CvPOSITObject **),
1> _Empty_deleter=false
1> ]
1> C:\MyDir\Myfile.hpp(71) : see reference to class template instantiation 'std::unique_ptr<_Ty,_Dx>' being compiled
1> with
1> [
1> _Ty=CvPOSITObject,
1> _Dx=void (CvPOSITObject **)
1> ]
Run Code Online (Sandbox Code Playgroud)
我该怎么做?
您的代码有两个问题.正如BenVoigt在他的回答中提到的那样,第一个是decltype不会触发从函数类型到指针到函数类型的隐式转换,因此必须明确地获取函数的地址.您的代码更改为
positObject = unique_ptr<CvPOSITObject,
decltype(&cvReleasePOSITObject)>(
cvCreatePOSITObject(param1, param2),
cvReleasePOSITObject);
Run Code Online (Sandbox Code Playgroud)
但是,由于不同的原因,现在无法编译,这将我们带入第二个问题.cvReleasePOSITObject采用类型的参数,CvPOSITObject **但unique_ptr上面将尝试调用其删除CvPOSITObject *.要解决此问题,只需对删除器使用lambda表达式.
positObject = unique_ptr<CvPOSITObject,
void(*)(CvPOSITObject *)>(
cvCreatePOSITObject(param1, param2),
[](CvPOSITObject *p) { cvReleasePOSITObject(&p); });
Run Code Online (Sandbox Code Playgroud)
如果要分离声明和初始化,则unique_ptr有几个选项.第一个示例演示了如何为此使用lamda表达式.
auto deleter = [](int *p) {
delete p;
};
int main()
{
std::unique_ptr<int, decltype(deleter)> p(nullptr, deleter);
p.reset(new int(42));
}
Run Code Online (Sandbox Code Playgroud)
您仍然必须将删除器实例传递给它unique_ptr,否则它将尝试默认构造删除器,这会失败,因为从lambda表达式生成的闭包已删除默认构造函数(N3691中的§5.1.2/ 20).
另一种选择是将删除器编写为函子,允许默认构造.
struct deleter
{
void operator()(int *p) const
{
delete p;
}
};
int main()
{
std::unique_ptr<int, deleter> p;
p.reset(new int(42));
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2346 次 |
| 最近记录: |