shared_ptr和COM对象

时间:2015-12-21 16:21:12

标签: c++11 gcc com shared-ptr

我有一个名为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,输出相同。

1 个答案:

答案 0 :(得分:0)

首先,函数调用绑定比成员指针取消引用更紧,所以你需要这些括号:

(p->*member)(&pointer);

(根据您的喜好将演员阵容添加到void。)

其次,您可以通过明确指定T的参数来改进调用语法;你应该不需要那个可怕的演员:

auto doc = create_new<IDocument>(factory, &IFactory::CreateDocument);