将MFC宏与模板一起使用
Using MFC macros with templates
是否可以从MFC类(如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()
以上未能编译,消息序列如下所示;
warning C4002: too many actual parameters for macro 'BEGIN_MESSAGE_MAP'
error C2653: 'TYPE' : is not a class or namespace name
除了手动展开MFC宏之外,还有其他解决方法吗?在这一点上,我不能使用模板专业化,正如这里的一个类似问题中所给出的,因为我不知道TYPE和ARG_TYPE的所有可能值。
另一种看待这个问题的方法是"我可以在不专门化模板或使宿主类成为模板类的情况下将模板类嵌入另一个类中吗?"。我也不能回答这个问题,我怀疑答案可能是否定的。
编辑MSDN上单一类型模板的部分解决方案,点击此处
您必须使用BEGIN_TEMPLATE_MESSAGE_MAP而不是BEGIN_MESSAGE_MAP。
宏和模板更常见的问题是因为宏是愚蠢的(tm)。
预处理器不关心<>
或[]
作为分组运算符,因此在解析宏调用时:
BEGIN_MESSAGE_MAP(CGlobalEditT<TYPE,ARG_TYPE>, CDialog)
翻译过来就是:
- 宏名称:
BEGIN_MESSAGE_MAP
- 参数1:
CGlobalEditT<TYPE
- 参数2:
ARG_TYPE>
- 自变量3:
CDialog
然后查找BEGIN_MESSAGE_MAP
的定义,意识到它是一个只有2个参数的宏,并低声抱怨。
有两种情况可能发生这种情况:
- 在类或函数中
- 实际声明模板类或模板函数
在后一种情况下,除非提供了特定的宏,否则您或多或少都会陷入困境。
在前一种情况下,您有两种解决方案:
- 使用
typedef
为不包含逗号的CGlobalEditT<TYPE,ARG_TYPE>
提供同义词 - 在
CGlobalEditT<TYPE,ARG_TYPE>
周围使用大括号来"隔离"逗号
当支架工作时,它很好,但情况并非总是如此。
当他们不这样做时,typedef
通常是一个合适的替代方案。
在任何情况下,都需要记住宏。
相关文章:
- 如何将enable-if与模板参数和参数包一起使用
- 如何将PERF_AMPLE_READ与mmap一起使用
- 如何将两个不同矢量的同一位置的两个元素组合在一起
- 如何将C++中的库和头与MinGW一起使用
- C++ MFC Libraries in Travis CI
- 将--whole archive链接器选项与CMake和具有其他库依赖项的库一起使用
- 为什么我不能将 rand() 与数组的大小一起使用?
- 要与"if constexpr"一起使用的编译时消息(在预处理器之后)
- 不能将复制初始化与隐式转换的多个步骤一起使用
- 将fold表达式与std::一起用于两个元组
- spdlog标头仅与外部fmt一起使用.spdlog错误:'内部':不是'fmt'
- 将 std::allocate_shared 与多态资源分配器一起使用
- 为什么常量词在重载运算符中不与 ostream 对象一起使用<<?
- 将 OpenCV 与 CMAKE 中的项目一起构建为第三方库的正确方法
- 将 exprtk 与自定义类的对象一起使用
- 将旧版本的MFC与新版本的Visual Studio一起使用
- MFC:CMFCToolBar SetButtonStyle 不与样式TBBS_PRESSED一起旋转
- 将MFC宏与模板一起使用
- MFC:将 GetContextMenuManager()->ShowPopup 与 Office2007 视觉对象一起使用时的延迟
- 我已经将CLIPS与VC++(MFC)集成在一起,为什么有些函数无法执行,例如"strcmp"