shared_ptr 和 COM 对象
shared_ptr and COM object
我有一个名为 factory (IFactory
) 的 COM 对象,它有几个方法,例如
virtual HRESULT STDMETHODCALLTYPE CreateDatabase(IDatabase** Result) = 0;
virtual HRESULT STDMETHODCALLTYPE CreateProcessor(IProcessor** Result) = 0;
virtual HRESULT STDMETHODCALLTYPE CreateDocument(IDocument** Result) = 0;
.....
当我需要创建一个 IDocument
时,我需要这样做:
IDocument* doc = nullptr;
factory->CreateDocument(&doc);
// some code here;
doc.Release();
所以我想创建一个通用函数来执行此操作并生成一个 shared_ptr
,所以我不需要手动释放它。
我创建了一个这样的函数:
template <typename T, typename K>
shared_ptr<T> create_new(K* p, HRESULT (K::*member)(T**)) {
T* pointer = nullptr;
(void)p->*member(&pointer);
shared_ptr<T> result(pointer, [=](T* o) {
o->Release();
});
return result;
}
这样,当我需要创建一个新的 IDocument
时,我只需要:
auto doc = create_new(factory, &IFactory::CreateDocument);
// do not need release it manually
但这不起作用,因为编译器需要更多信息来实例化模板,所以我使用
auto doc = create_new(factory, (HRESULT (IFactory::*)(IDocument**))&IFactory::CreateDocument);
这种方式似乎是正确的,但是当我编译我的代码时,编译器停止在
(void)p->*member(&pointer);
并说:
must use '.*' or '->*' to call pointer-to-member function in 'member (...)', e.g. '(... ->* member) (...)'
In instantiation of 'std::shared_ptr<_Tp1> create_new(K*, HRESULT (K::*)(T**)) [with T = IDocument; K = IFactory; HRESULT = long int]'
谁能帮我解决这个问题?
编译器是 MinGW-w64 GCC 4.8.5,但我试过 GCC 5.3.0,输出相同。
首先,函数调用比成员指针解引用绑定得更紧密,因此您需要这些括号:
(p->*member)(&pointer);
(根据需要将演员表添加到 void
)。
其次,您可以通过显式指定 T
的参数来改进调用语法;那么你应该不需要可怕的演员表:
auto doc = create_new<IDocument>(factory, &IFactory::CreateDocument);
我有一个名为 factory (IFactory
) 的 COM 对象,它有几个方法,例如
virtual HRESULT STDMETHODCALLTYPE CreateDatabase(IDatabase** Result) = 0;
virtual HRESULT STDMETHODCALLTYPE CreateProcessor(IProcessor** Result) = 0;
virtual HRESULT STDMETHODCALLTYPE CreateDocument(IDocument** Result) = 0;
.....
当我需要创建一个 IDocument
时,我需要这样做:
IDocument* doc = nullptr;
factory->CreateDocument(&doc);
// some code here;
doc.Release();
所以我想创建一个通用函数来执行此操作并生成一个 shared_ptr
,所以我不需要手动释放它。
我创建了一个这样的函数:
template <typename T, typename K>
shared_ptr<T> create_new(K* p, HRESULT (K::*member)(T**)) {
T* pointer = nullptr;
(void)p->*member(&pointer);
shared_ptr<T> result(pointer, [=](T* o) {
o->Release();
});
return result;
}
这样,当我需要创建一个新的 IDocument
时,我只需要:
auto doc = create_new(factory, &IFactory::CreateDocument);
// do not need release it manually
但这不起作用,因为编译器需要更多信息来实例化模板,所以我使用
auto doc = create_new(factory, (HRESULT (IFactory::*)(IDocument**))&IFactory::CreateDocument);
这种方式似乎是正确的,但是当我编译我的代码时,编译器停止在
(void)p->*member(&pointer);
并说:
must use '.*' or '->*' to call pointer-to-member function in 'member (...)', e.g. '(... ->* member) (...)'
In instantiation of 'std::shared_ptr<_Tp1> create_new(K*, HRESULT (K::*)(T**)) [with T = IDocument; K = IFactory; HRESULT = long int]'
谁能帮我解决这个问题?
编译器是 MinGW-w64 GCC 4.8.5,但我试过 GCC 5.3.0,输出相同。
首先,函数调用比成员指针解引用绑定得更紧密,因此您需要这些括号:
(p->*member)(&pointer);
(根据需要将演员表添加到 void
)。
其次,您可以通过显式指定 T
的参数来改进调用语法;那么你应该不需要可怕的演员表:
auto doc = create_new<IDocument>(factory, &IFactory::CreateDocument);