Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Template and preprocessor macros

Template and preprocessor macros

Scheduled Pinned Locked Moved C / C++ / MFC
c++debugginghelptutorialquestion
5 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • R Offline
    R Offline
    rrrado
    wrote on last edited by
    #1

    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.

    C N 2 Replies Last reply
    0
    • R rrrado

      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.

      C Offline
      C Offline
      Code o mat
      wrote on last edited by
      #2

      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. <

      1 Reply Last reply
      0
      • R rrrado

        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.

        N Offline
        N Offline
        Niklas L
        wrote on last edited by
        #3

        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)
        #endif

        If 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()));
        }

        home

        R 1 Reply Last reply
        0
        • N Niklas L

          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)
          #endif

          If 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()));
          }

          home

          R Offline
          R Offline
          rrrado
          wrote on last edited by
          #4

          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.

          N 1 Reply Last reply
          0
          • R rrrado

            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.

            N Offline
            N Offline
            Niklas L
            wrote on last edited by
            #5

            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)

            home

            modified on Tuesday, June 15, 2010 9:22 AM

            1 Reply Last reply
            0
            Reply
            • Reply as topic
            Log in to reply
            • Oldest to Newest
            • Newest to Oldest
            • Most Votes


            • Login

            • Don't have an account? Register

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • World
            • Users
            • Groups