将MFC宏与模板一起使用

Sma*_*acL 4 c++ mfc templates

是否可以从Mial类(如CDialog)派生和使用C++模板类.我已经尝试过,但实现过程中使用了用于消息路由的MFC宏.例如;

template<class TYPE, class ARG_TYPE>
class CMyDialogT : public CDialog
{
public:
    CMyDialogT(CMyContainerT<TYPE,ARG_TYPE> *pData,CWnd* pParent = NULL);  
    CMyContainerT<TYPE,ARG_TYPE> *m_pData;
    // Generated message map functions
    //{{AFX_MSG(CMyDialogT)
    afx_msg void OnUpdateMyControl();
    //}}AFX_MSG
    DECLARE_MESSAGE_MAP()
};

template<class TYPE, class ARG_TYPE>
CMyDialogT<TYPE,ARG_TYPE>::CMyDialogT(CMyContainerT<TYPE,ARG_TYPE> *pData,CWnd* pParent)
    : CDialog(CMyDialogT::IDD, pParent)
{
    m_pData = pData;
}

BEGIN_MESSAGE_MAP(CGlobalEditT<TYPE,ARG_TYPE>, CDialog)
    //{{AFX_MSG_MAP(CGlobalEditT)
    ON_EN_UPDATE(IDC_MY_CONTROL, OnUpdateMyControl)
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()
Run Code Online (Sandbox Code Playgroud)

以上内容无法使用一系列消息进行编译,如下所示;

 warning C4002: too many actual parameters for macro 'BEGIN_MESSAGE_MAP'
 error C2653: 'TYPE' : is not a class or namespace name
Run Code Online (Sandbox Code Playgroud)

除了手动展开MFC宏之外,还有其他解决方法吗?我现在不能使用模板特化,如同在类似问题中给出的那样,因为我不知道TYPE和ARG_TYPE的所有可能值.

查看问题的另一种方法是"我可以在另一个类中嵌入模板类,而无需专门化模板或使主机类成为模板类".我也不能回答这个,我怀疑答案可能是否定的.

MSDN编辑单一类型模板的部分解决方案

Jav*_*dro 5

您必须使用BEGIN_TEMPLATE_MESSAGE_MAP而不是BEGIN_MESSAGE_MAP.

  • 我没有检查你的代码,抱歉……我只是阅读了消息映射和模板,并考虑了 BEGIN_TEMPLATE_MESSAGE_MAP。不管怎样,很高兴知道你解决了你的问题! (2认同)

Mat*_* M. 5

宏和模板的更普遍的问题是因为宏是愚蠢的(tm)。

预处理器不关心<>[]作为分组运算符,因此在解析宏调用时:

BEGIN_MESSAGE_MAP(CGlobalEditT<TYPE,ARG_TYPE>, CDialog)
Run Code Online (Sandbox Code Playgroud)

它翻译成:

  • 宏名称: BEGIN_MESSAGE_MAP
  • 论点1: CGlobalEditT<TYPE
  • 论点2: ARG_TYPE>
  • 论点3: CDialog

然后查找 的定义BEGIN_MESSAGE_MAP,发现它是一个只有 2 个参数的宏,并低声抱怨。

有两种情况会发生这种情况:

  • 在类或函数中
  • 实际声明模板类或模板函数

在后一种情况下,除非提供了特定的宏,否则您或多或少会被搞砸。

在前一种情况下,您有两种解决方案:

  • 使用 atypedef提供CGlobalEditT<TYPE,ARG_TYPE>不包含逗号的同义词
  • 使用大括号CGlobalEditT<TYPE,ARG_TYPE>来“隔离”逗号

当牙套起作用时,这很好,但情况并非总是如此。

当他们不这样做时,typedef通常是一个合适的选择。

无论如何,关于宏是需要牢记的。