【发布时间】:2018-02-07 19:18:28
【问题描述】:
我在学习 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;
}
到目前为止一切顺利,现在是棘手的问题。 (几乎)所有返回另一个 COM+ 对象的 COM+ 方法都将返回上述接口作为指向方法参数列表指针的指针,例如
HRESULT WINAPI IXMLDOMDocument::selectSingleNode(BSTR, IXMLDOMNode**)
我想/需要调用一些(成员)函数,它可以给我结果指针作为它的返回值,像这样:
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"));
这个解决方案困扰我的是,我必须指定返回类型 (IXMLDOMNode),即使编译器知道它的类型(每个人都会同意,它是IXMLDOMDocument::selectSingleNode方法)
所以,最后,这篇长篇文章被简化为:是否可以使用某种模板元编程+宏巫术来推断该参数类型而无需指定它?
提前致谢!!
【问题讨论】:
-
仅供参考,这没关系。对于生产代码,从 IDL 或类型库生成的代码开始。
-
使用 IDL 生成的代码是什么意思?
标签: c++ winapi template-meta-programming com+