# Macro question (C++)

## Recommended Posts

d000hg    1199
I have a macro which is something like this:
#define CREATE_FUNCTOR(name,method) struct name {  void method(); };
This isn't exact so don't focus on why I want to do this! My problem is that I want the struct to be called _name, not name. If I change the macro to be:
#define CREATE_FUNCTOR(name,method) struct _name {  void method(); };
Then I get a struct called "_name". Is it possible to get the preproccesor to understand I want to stick '_' onto the front of the variable? (It's actually for a message handling thing and I want to create a functor called _OnXXX for each event-handler OnXXX)

##### Share on other sites
nhatkthanh    334
I think you want to do this.

#define CREATE_FUNCTOR(name,method) struct _##name { void method(); };

##### Share on other sites
jpetrie    13138
Gross. Prefixing identifers with an underscore is naughty. But what you want is ##, the token pasting operator.

#define foo(a) _##a    // foo(bar) --> _bar

##### Share on other sites
d000hg    1199
Thanks guys. I agree it's ugly to use macros for this at all but I don't think C++ makes what I want possible through normal means (I'm making something a little like MFC).

##### Share on other sites
Sneftel    1788
It is in particular naughty to just use an underscore, though, because it is extremely likely that someone using your framework will want to use that name. Don't make it _whatever. At the very least, make it __AUTO__d000hgsframework__whatever or suchlike.

##### Share on other sites
Nitage    1107
Quote:
 Original post by SneftelIt is in particular naughty to just use an underscore, though, because it is extremely likely that someone using your framework will want to use that name. Don't make it _whatever. At the very least, make it __AUTO__d000hgsframework__whatever or suchlike.

He should be careful with the CREATE_FUNCTOR identifier as it's a macro, but the _name identifier is fine, as it obeys scoping rules.

Also, the identifier __AUTO__d000hgsframework__ is reserved to the compiler and standard library.

##### Share on other sites
Zahlman    1682
Quote:
 Original post by d000hgI have a macro which is something like this:#define CREATE_FUNCTOR(name,method) struct name { void method(); };This isn't exact so don't focus on why I want to do this!

Sorry, I must insist. You are aware of std::mem_fun and std::mem_fun_ref, yes? I'm pretty sure there's *something* that solves your problem more nicely...

##### Share on other sites
swiftcoder    18437
Quote:
 Original post by ZahlmanSorry, I must insist. You are aware of std::mem_fun and std::mem_fun_ref, yes? I'm pretty sure there's *something* that solves your problem more nicely...

And if those don't do what you need, how about boost::function and boost::bind?
I can guarrentee they will do more than you can do with your macros [grin]

##### Share on other sites
demonkoryu    980
Quote:
 Original post by Nitage[...]Also, the identifier __AUTO__d000hgsframework__ is reserved to the compiler and standard library.

</sarcasm>.

May I conclude that you think using identifiers like this is OK, in spite of the holy?

To come out, yes, I use #ifndef __MYFREAKINGFILENAME_H... all the time. [smile]

##### Share on other sites
rip-off    10979
Quote:
Original post by Konfusius
Quote:
 Original post by Nitage[...]Also, the identifier __AUTO__d000hgsframework__ is reserved to the compiler and standard library.

</sarcasm>.

May I conclude that you think using identifiers like this is OK, in spite of the holy?

To come out, yes, I use #ifndef __MYFREAKINGFILENAME_H... all the time. [smile]

Why type 2 extra characters just to risk breaking your program? [smile]

##### Share on other sites
Sneftel    1788
Quote:
 Original post by NitageHe should be careful with the CREATE_FUNCTOR identifier as it's a macro, but the _name identifier is fine, as it obeys scoping rules.

I don't think you quite understand. The point is that the user--who shouldn't have to know what identifiers are being generated by CREATE_FUNCTOR--may end up using exactly that name, and then becoming quite confused when it collides with an identifier he doesn't know he's already defined.

##### Share on other sites
d000hg    1199
Quote:
Original post by Zahlman
Quote:
 Original post by d000hgI have a macro which is something like this:#define CREATE_FUNCTOR(name,method) struct name { void method(); };This isn't exact so don't focus on why I want to do this!

Sorry, I must insist. You are aware of std::mem_fun and std::mem_fun_ref, yes? I'm pretty sure there's *something* that solves your problem more nicely...

I don't think I can use these but I'll try and remember to check. In fact you can see the real macros...
#define CREATE_HANDLER(DLG_NAME,HANDLER_NAME) /void HANDLER_NAME(); /struct HANDLER_NAME##_functor : public GUIEventHandlerBase /{ /	DLG_NAME *m_pThis; /	inline void On() { m_pThis->HANDLER_NAME(); } /	HANDLER_NAME##_functor(DLG_NAME *pThis) : m_pThis(pThis){} /};#define REGISTER_HANDLER(ID,EVENT,HANDLER) RegisterEventHandler(ID,EVENT,new HANDLER##_functor(this));

And the way they are used in header and source file:
class MainMenuDlg : public GUIDialog  {protected:	const static std::string Template;	GameState *m_pGameState;public:	MainMenuDlg(GUIManager *pManager,GameState *pGameState);	virtual ~MainMenuDlg();	void LoadSaveGame(char *name);	CREATE_HANDLER(MainMenuDlg , OnQuit)	CREATE_HANDLER(MainMenuDlg , OnLoad)	CREATE_HANDLER(MainMenuDlg , OnNewGame)};

const std::string MainMenuDlg::Template = "MainMenu";MainMenuDlg::MainMenuDlg(GUIManager *pManager,GameState *pGameState): GUIDialog(pManager,Template), m_pGameState(pGameState){	SetPos(0,0);	SetSize(1,1);	m_pGUIManager->LockWindow(this,true);	REGISTER_HANDLER("BTN_EXIT",BUTTON_LCLICK,OnQuit)	REGISTER_HANDLER("BTN_NEW",BUTTON_LCLICK,OnNewGame)	REGISTER_HANDLER("BTN_LOAD",BUTTON_LCLICK,OnLoad)}void MainMenuDlg::OnQuit(){}	void MainMenuDlg::OnLoad(){}void MainMenuDlg::OnNewGame(){}

The macros are ugly but the end result is quite nice - not safe or proper C++ I'm sure - I want the user to have it this easy to use but not have to resort to nasty macros (as much) if possible.

##### Share on other sites
Zahlman    1682
Something like this should do it:

template <typename DLG>class boundPfn : public GUIEventHandlerBase {  typedef DLG::void(*)() pfn_t;  DLG * dlg;  pfn_t pfn;  boundPfn(DLG* dlg, pfn_t pfn) : dlg(dlg), pfn(pfn) {}  void operator()() { ((*dlg).*(pfn)); }  // why use a member function rather than operator() overload?};// This macro is kinda marginal... Normally this kind of work would be done// with a function (in order to infer type for class instantiation), but this// saves a little more typing over that approach#define REGISTER_EVENT(id, event, classname, handler) RegisterEventHandler(id, event, new boundPfn<classname>(this, &##classname##::##handler))// In MainMenuDlgREGISTER_EVENT("BTN_EXIT", BUTTON_LCLICK, MainMenuDlg, OnQuit);

As an added bonus (heh), you only declare one extra type per DLG class, rather than one extra type per handler.

##### Share on other sites
d000hg    1199
That looks like I can just drop it in and replace my existing #define - I'll give it a try because it looks a bit nicer.

Thanks.