Template and preprocessor macros
-
I have simple template method in my class. I think it is self-explaining:
template<class T> T\* GetCell(int row,int col) { return ((T\*)GridCellGet(col,row,0,0,RUNTIME\_CLASS(T))); }
It works in debug build (MFC DLL), but it does not compile in release (static) build. It seems RUNTIME_CLASS() has different definition for DLL and static builds. Error message is:
error C2039: 'classT' : is not a member of ....
It teems preprocessor replaces RUNTIME_CLASS(T) with 'T' instead of type name, I guess it has higher priority. Do you have idea how to solve this? Thank you. -
I have simple template method in my class. I think it is self-explaining:
template<class T> T\* GetCell(int row,int col) { return ((T\*)GridCellGet(col,row,0,0,RUNTIME\_CLASS(T))); }
It works in debug build (MFC DLL), but it does not compile in release (static) build. It seems RUNTIME_CLASS() has different definition for DLL and static builds. Error message is:
error C2039: 'classT' : is not a member of ....
It teems preprocessor replaces RUNTIME_CLASS(T) with 'T' instead of type name, I guess it has higher priority. Do you have idea how to solve this? Thank you.Use
#ifdef __DEBUG__
to compile differently in debug and release?> The problem with computers is that they do what you tell them to do and not what you want them to do. < > Computers don't kill programs, users kill programs < > "It doesn't work, fix it" does not qualify as a bug report. <
-
I have simple template method in my class. I think it is self-explaining:
template<class T> T\* GetCell(int row,int col) { return ((T\*)GridCellGet(col,row,0,0,RUNTIME\_CLASS(T))); }
It works in debug build (MFC DLL), but it does not compile in release (static) build. It seems RUNTIME_CLASS() has different definition for DLL and static builds. Error message is:
error C2039: 'classT' : is not a member of ....
It teems preprocessor replaces RUNTIME_CLASS(T) with 'T' instead of type name, I guess it has higher priority. Do you have idea how to solve this? Thank you.Goto declaration of RUNTIME_CLASS macro in afx.h and you will see something like
#define _RUNTIME_CLASS(class_name) ((CRuntimeClass*)(&class_name::class##class_name))
#ifdef _AFXDLL
#define RUNTIME_CLASS(class_name) (class_name::GetThisClass())
#else
#define RUNTIME_CLASS(class_name) _RUNTIME_CLASS(class_name)
#endifIf you have _AFXDLL defined in your project replace RUNTIME_CLASS(T) with T::GetThisClass() Otherwise you will have a problem. The macro will expand to &T::classT which will fail, and you will need some other construct. Edit: This might work (NOT tested)
template<class T> T* GetCell(int row,int col)
{
return ((T*)GridCellGet(col,row,0,0,T().GetRuntimeClass()));
} -
Goto declaration of RUNTIME_CLASS macro in afx.h and you will see something like
#define _RUNTIME_CLASS(class_name) ((CRuntimeClass*)(&class_name::class##class_name))
#ifdef _AFXDLL
#define RUNTIME_CLASS(class_name) (class_name::GetThisClass())
#else
#define RUNTIME_CLASS(class_name) _RUNTIME_CLASS(class_name)
#endifIf you have _AFXDLL defined in your project replace RUNTIME_CLASS(T) with T::GetThisClass() Otherwise you will have a problem. The macro will expand to &T::classT which will fail, and you will need some other construct. Edit: This might work (NOT tested)
template<class T> T* GetCell(int row,int col)
{
return ((T*)GridCellGet(col,row,0,0,T().GetRuntimeClass()));
} -
Thank you, it works, but I think it always creates temporary object so it will be bit inefficient but maybe it won't be noticeable problem.
Ok. If performance is critical, you could solve this by having a class variable (static T temp) to use to avoid the constructor each time. Who knows, that construct might even win you some kind of most-akward-contruct-of-the-year award. <edit>Ah forget about that and just cache the return value of T().GetRuntimeClass(). </edit> It's a bit fishy that you had different behavior in debug and release. You might want to check what defines you have in release vs debug. If _AFXDLL is defined in debug it should be defined in release as well. Notice that it's implicitly defined when defining some other symbols like _AFXEXT (and what else)
modified on Tuesday, June 15, 2010 9:22 AM