6

I would like to write a C++ macro taking arbitrary argument like:

#define MANIP(...) \ 
//Implementation

Such that writing

MANIP(m_a, m_b, m_c);

expands to

f(a, b, c);
g("a", "b", "c");

Is this possible?

Thank you in advance for helping me with this seemingly extravagant question :)

a3f
  • 8,517
  • 1
  • 41
  • 46
StephQ
  • 2,032
  • 3
  • 19
  • 27

3 Answers3

6

I don't believe there will be an easy way to go from m_a to a. However, the stringize operator # is part of standard C and C++.

for example, given

#define STRING(x) #x

then STRING(m_a) will be transformed to "m_a".

Derrick Turk
  • 4,246
  • 1
  • 27
  • 27
0

The preprocessor cannot split tokens. This means it is impossible to produce foo from m_foo or (as has recently been asked) foo from "foo".

If you can use variadic macros (as Matthieu M. points out, this means C99 or C++0x) Jens Gustedt’s P99 library would be helpful here. There are macros to make this even easier, but let’s make this readable to people who aren’t familiar with the library, OK?

Simplified case: there are either two or three arguments passed.

#define MANIP2(a, b) \
    f(a, b)          \
    g(#a, #b)

#define MANIP3(a, b, c) \
    f(a, b, c)          \
    g(#a, #b, #c)

#define MANIP(...)   \
    MANIP_(          \
        P99_PASTE2(MANIP, P99_NARG(__VA_ARGS__)), \
        __VA_ARGS__) \

#define MANIP_(MANIPMAC, ...) MANIPMAC(__VA_ARGS__)

This illustrates the basic principle. In practice, there are foreach-style macros (analogous to Boost’s) to make this easier to code (though, as I mentioned, harder to read for the uninitiated). See the P99 library documentation for details.

J. C. Salomon
  • 4,143
  • 2
  • 29
  • 38
-1

It's not really possible to have the pre-processor (which is what handles #define statements, not the C++ compiler itself) break arguments into parts. So if you're trying to extract the a from m_a you can't do it. Instead it'd be better to define your macro like:

  #define MANIP(m, a, b, c)

And require the 'm' to be a separate input.

Secondly, you can't easily convert from non-string inputs to string inputs. IE, converting from a to "a" isn't easily doable. I'm phrasing it that way since I know some CPPs (C-Pre-processor) can do it. But I don't think it's portable.

Generally when you're trying to do complex things, you should be working with the programming language rather than the CPP.

Specifically, in C++ you have templates which will let you get a lot farther with work like that than #define statements for the CPP.

Wes Hardaker
  • 21,735
  • 2
  • 38
  • 69
  • 4
    The stringize macro operation #a -> "a" is bog standard. – Jim Lewis Jan 28 '11 at 19:46
  • Just to clarify, I am perfectly fine with C99 macro operations, as they are going to be supported in C++0X. I know about templates, but for the specific problem I am facing the proposed solution would be the best one. The second best would be to write MANIP(a, b, c) which should be easier to do (I know how to forward each argument of __VA_ARGS__ to a separate macro taking one argument). – StephQ Jan 28 '11 at 19:47