S
skydivergm
Hi,
Consider the following code:
---
template <class T>
class TMyCWndWrapper : public T
{
public:
afx_msg void OnEnable(BOOL bEnable)
{
// For the sake of simplicity I'll just call the base class imp.
T::OnEnable(bEnable);
}
DECLARE_MESSAGE_MAP()
};
// Define a custom template IMPLEMENT_MESSAGE_MAP
#define WND_TEMPLATE_IMPLEMENT_MESSAGE_MAP(baseClass) \
BEGIN_MESSAGE_MAP(TMyCWndWrapper< baseClass >, baseClass) \
ON_WM_ENABLE() \
END_MESSAGE_MAP()
WND_TEMPLATE_IMPLEMENT_MESSAGE_MAP( CListBox );
WND_TEMPLATE_IMPLEMENT_MESSAGE_MAP( CListCtrl );
---
This code compiles just fine in VC6.
In VC8, I get the following error:
error C2906: 'const AFX_MSGMAP
*TMyCWndWrapper<T>::GetThisMessageMap(void)' : explicit specialization
requires 'template <>'
So I went on and implemented my own BEGIN_TEMPLATE_MESSAGE_MAP and
added the "template <>" where needed.
When I compiled, I had a macro redefinition on
BEGIN_TEMPLATE_MESSAGE_MAP. It turns out that MFC already took care of
that, so I removed my implementation and used MFC's with the adjusted
line:
BEGIN_TEMPLATE_MESSAGE_MAP(TMyCWndWrapper, baseClass , baseClass)
Now, if I define only the first line:
WND_TEMPLATE_IMPLEMENT_MESSAGE_MAP( CListBox );
The code actually compiles, but if I add the other line:
WND_TEMPLATE_IMPLEMENT_MESSAGE_MAP( CListCtrl );
Now I get the error:
error C2995: 'const AFX_MSGMAP *TMyCWndWrapper<T>::GetMessageMap(void)
const' : function template has already been defined.
My current status is that I re-implemented BEGIN_TEMPLATE_MESSAGE_MAP
as follows:
---
#undef BEGIN_TEMPLATE_MESSAGE_MAP
#define BEGIN_TEMPLATE_MESSAGE_MAP(theClass, type_name, baseClass) \
PTM_WARNING_DISABLE \
template <> \
const AFX_MSGMAP* theClass< type_name >::GetMessageMap() const \
{ return GetThisMessageMap(); } \
template <> \
const AFX_MSGMAP* PASCAL theClass< type_name >::GetThisMessageMap() \
{ \
typedef theClass< type_name > ThisClass; \
typedef baseClass TheBaseClass; \
static const AFX_MSGMAP_ENTRY _messageEntries[] = \
{
---
The diff. between this one and MFC's is that I replaced:
template < typename type_name >
with:
template <>
---
The code now compiles just fine.
So, in case this helps someone, I'll be very happy.
Beyond that, if someone would like to explain what's going on here I
will be happy to receive an answer.
I don't understand what "template < typename type_name >" means.
Cheers.
Consider the following code:
---
template <class T>
class TMyCWndWrapper : public T
{
public:
afx_msg void OnEnable(BOOL bEnable)
{
// For the sake of simplicity I'll just call the base class imp.
T::OnEnable(bEnable);
}
DECLARE_MESSAGE_MAP()
};
// Define a custom template IMPLEMENT_MESSAGE_MAP
#define WND_TEMPLATE_IMPLEMENT_MESSAGE_MAP(baseClass) \
BEGIN_MESSAGE_MAP(TMyCWndWrapper< baseClass >, baseClass) \
ON_WM_ENABLE() \
END_MESSAGE_MAP()
WND_TEMPLATE_IMPLEMENT_MESSAGE_MAP( CListBox );
WND_TEMPLATE_IMPLEMENT_MESSAGE_MAP( CListCtrl );
---
This code compiles just fine in VC6.
In VC8, I get the following error:
error C2906: 'const AFX_MSGMAP
*TMyCWndWrapper<T>::GetThisMessageMap(void)' : explicit specialization
requires 'template <>'
So I went on and implemented my own BEGIN_TEMPLATE_MESSAGE_MAP and
added the "template <>" where needed.
When I compiled, I had a macro redefinition on
BEGIN_TEMPLATE_MESSAGE_MAP. It turns out that MFC already took care of
that, so I removed my implementation and used MFC's with the adjusted
line:
BEGIN_TEMPLATE_MESSAGE_MAP(TMyCWndWrapper, baseClass , baseClass)
Now, if I define only the first line:
WND_TEMPLATE_IMPLEMENT_MESSAGE_MAP( CListBox );
The code actually compiles, but if I add the other line:
WND_TEMPLATE_IMPLEMENT_MESSAGE_MAP( CListCtrl );
Now I get the error:
error C2995: 'const AFX_MSGMAP *TMyCWndWrapper<T>::GetMessageMap(void)
const' : function template has already been defined.
My current status is that I re-implemented BEGIN_TEMPLATE_MESSAGE_MAP
as follows:
---
#undef BEGIN_TEMPLATE_MESSAGE_MAP
#define BEGIN_TEMPLATE_MESSAGE_MAP(theClass, type_name, baseClass) \
PTM_WARNING_DISABLE \
template <> \
const AFX_MSGMAP* theClass< type_name >::GetMessageMap() const \
{ return GetThisMessageMap(); } \
template <> \
const AFX_MSGMAP* PASCAL theClass< type_name >::GetThisMessageMap() \
{ \
typedef theClass< type_name > ThisClass; \
typedef baseClass TheBaseClass; \
static const AFX_MSGMAP_ENTRY _messageEntries[] = \
{
---
The diff. between this one and MFC's is that I replaced:
template < typename type_name >
with:
template <>
---
The code now compiles just fine.
So, in case this helps someone, I'll be very happy.
Beyond that, if someone would like to explain what's going on here I
will be happy to receive an answer.
I don't understand what "template < typename type_name >" means.
Cheers.