C++ COM+ 方法参数推导

C++ COM+ method argument deduction

我在学习 C++ 模板元编程的过程中遇到了一些麻烦。我正在尝试创建一些 COM+ 包装器,以便我将它们与 C++ 混合在一起的生活变得更快乐 :)

我的第一步是创建一个智能指针,它通过 Release 方法管理 COM+ 对象:

template <typename COM>
using com_ptr = std::shared_ptr<COM>;

template<class COM>
com_ptr<COM> make_com_ptr(COM **ppv)
{
    auto ret = com_ptr<COM>(*ppv, [](COM *p) { if (p) p->Release(); });
    *ppv = NULL;
    return ret;
}

到目前为止一切顺利,现在是棘手的一点。 (几乎)所有 return 另一个 COM+ 对象的 COM+ 方法都会 return 上述接口作为指向方法参数列表上的指针的指针,例如 HRESULT WINAPI IXMLDOMDocument::selectSingleNode(BSTR, IXMLDOMNode**)

我 want/need 调用一些(成员)函数,它可以给我那个结果指针作为它的 return 值,像这样:

IXMLDOMDocument *prawDoc(nullptr);
CoCreateInstance(..., reinterpret_cast<LPVOID*>(&prawDoc));
auto pDoc = make_com_ptr(&prawDoc);
com_ptr<IXMLDOMNode> pNode = FX(pDoc, &IXMLDOMDocument::selectSingleNode,_bstr_t("//xpath"));
^^(auto pNode = ...)         ^^ (the function)

现在,到目前为止我得到的是:

template<typename COMRET, typename COM, typename METHOD, typename A1>
com_ptr<COMRET> _prv_com_comret(com_ptr<COM> This, const METHOD &Method, A1 Arg1)
{
    COMRET *ppv(nullptr);
    ::SetLastError((*This.*Method)(Arg1, &ppv));
    return make_com_ptr(&ppv);
}

#define com_comret( COM, This, Method, ... )\
    _prv_com_comret<COM>( This, &decltype(This)::_Ptr_base::element_type::Method, __VA_ARGS__ )

所以,有了这个模板函数和宏,我可以这样写:

auto pNode = com_comret(IXMLDOMNode, pDoc, selectSingleNode, _bstr_t("//xpath"));

这个解决方案让我困扰的是我必须指定return类型(IXMLDOMNode),即使编译器确实知道它的类型(每个人都会同意,这是 IXMLDOMDocument::selectSingleNode 方法的最后一个参数)

所以,最后,这个长 post 被简化为:是否可以使用某种模板元编程+宏 魔法 来推断该参数类型而无需必须指定吗?

提前致谢!!

打开指向成员的指针类型,而不是使其不透明。

template<typename COMRET, typename COM, typename A1>
com_ptr<COMRET> _prv_com_comret(com_ptr<COM> This, COMRET (COM::* const Method)(A1, COMRET**), A1 Arg1)

这应该可以在没有明确指定模板参数的情况下调用。