是否可以从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上编辑单一类型模板的部分解决方案
您必须使用BEGIN_TEMPLATE_MESSAGE_MAP而不是BEGIN_MESSAGE_MAP.
宏和模板的更普遍的问题是因为宏是愚蠢的(tm)。
预处理器不关心<>
或[]
作为分组运算符,因此在解析宏调用时:
BEGIN_MESSAGE_MAP(CGlobalEditT<TYPE,ARG_TYPE>, CDialog)
Run Code Online (Sandbox Code Playgroud)
它翻译成:
BEGIN_MESSAGE_MAP
CGlobalEditT<TYPE
ARG_TYPE>
CDialog
然后查找 的定义BEGIN_MESSAGE_MAP
,发现它是一个只有 2 个参数的宏,并低声抱怨。
有两种情况会发生这种情况:
在后一种情况下,除非提供了特定的宏,否则您或多或少会被搞砸。
在前一种情况下,您有两种解决方案:
typedef
提供CGlobalEditT<TYPE,ARG_TYPE>
不包含逗号的同义词CGlobalEditT<TYPE,ARG_TYPE>
来“隔离”逗号当牙套起作用时,这很好,但情况并非总是如此。
当他们不这样做时,typedef
通常是一个合适的选择。
无论如何,关于宏是需要牢记的。
归档时间: |
|
查看次数: |
1558 次 |
最近记录: |