0

I have macro in which i pass an argument:

#define bind(id) function[function_id::id] = std::bind(otherFunction::id, std::placeholders::_1)

In that case id expands to whatever I write into macro while using it. However I would like to add some characters to one of them, like this:

#define bind(id) function[function_id::id] = std::bind(otherFunction::add_id, std::placeholders::_1)

So that first replacement of id is original and second is with sufix add_ . When I do that second expansion with add_ won't expand, so I end up with add_id instead of add_whatever_I_wanted.

In that case I've tried to use brackets and write it like that:

#define bind(id) function[function_id::id] = std::bind(otherFunction::add_(id), std::placeholders::_1)

And it worked partially, now id is wrapped into brackets and expansion result is

add_(whatever_I_wanted)

Instead of

add_whatever_I_wanted

It's killing me as I want to use it quite often. Is there any workaround?

melpomene
  • 84,125
  • 8
  • 85
  • 148
PStarczewski
  • 479
  • 2
  • 17
  • You'll have to use the string concatenation facilities of the preprocessor. Something along the lines of `other_function::STRCAT(add_, id)`. Please note that you'll have to define `STRCAT`. – R Sahu Sep 14 '18 at 22:37
  • 1
    You probably want `add_##id`. But if you want to pass another macro into `id` parameter, then you'll need several layers of indirection: something like `#define CAT(x,y) CAT_(x,y)` \n `#define CAT_(x,y) x##y` \n `... std::bind(otherFunction::CAT(add_,id) , ...` – HolyBlackCat Sep 14 '18 at 22:39
  • 1
    https://stackoverflow.com/questions/22975073/what-does-double-hash-do-in-a-preprocessor-directive, https://stackoverflow.com/questions/216875/what-are-the-applications-of-the-preprocessor-operator-and-gotchas-to-conside – melpomene Sep 14 '18 at 22:40
  • 1
    Look up the token pasting capability of the preprocessor using `##`. I'd query using the processor at all though (for anything except including standard headers), as distinct from simply writing separate dedicated function to do what you need. The preprocessor has a lot of down-sides, including not respecting scope. – Peter Sep 14 '18 at 22:40
  • Double hash worked like a charm. I was typing wrong questions into google therefore couldn't find satisfying topics on stack. Thanks! – PStarczewski Sep 14 '18 at 22:43
  • 1
    FWIW, I strongly recommend avoiding macros whenever possible, even if it means increased code duplication (within reason). It's impossible to tell what a macro interacts with just by looking at its use, meaning that anyone else looking at your code is going to be confused. If you must use macros, the convention is to name them in `ALL_CAPS` to avoid some of the problems with name collisions (e.g. your macro cause problems if anyone wrote `std::bind(...)`, because that would expand the macro). In this case: `#define BIND(id) ...` – Justin Sep 14 '18 at 22:54
  • @Justin unfortuantely in this particular case I have to. However thank you for advice, I will change naming convention and try to avoid them in the future. – PStarczewski Sep 14 '18 at 23:21
  • Somebody please make an answer to get this out of the list of unanswered questions. – Yunnosch Sep 17 '18 at 13:42

0 Answers0