我有一个名为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,输出相同。
答案 0 :(得分:0)
首先,函数调用绑定比成员指针取消引用更紧,所以你需要这些括号:
(p->*member)(&pointer);
(根据您的喜好将演员阵容添加到void
。)
其次,您可以通过明确指定T
的参数来改进调用语法;你应该不需要那个可怕的演员:
auto doc = create_new<IDocument>(factory, &IFactory::CreateDocument);