Bezeichner aus __VA_ARGS__



  • Hallo,

    Ich habe ein Variadic Makro, nennen wir es einmal ARGS(...). Nun möchte ich aus __VA_ARGS__ einen gültigen Bezeichner erstellen, der einfach allen Argumenten, nur ohne irgendwelche Trennzeichen entspricht.

    Beispiel:

    ARGS(int, double, char) // intdoublechar
    

    Gibts dafür was?

    Grüße
    PI



  • Wenn du einen C99- bzw. C++11-konformen Präprozessor hast (MSVC hat diesen bislang nicht), kann man das etwa so machen:

    #define PP_NARG( ...) PP_NARG_(__VA_ARGS__, PP_REV_N())
    #define PP_NARG_(...) PP_ARG_N(__VA_ARGS__)
    #define PP_ARG_N(                                       \
      A1 , A2 , A3 , A4 , A5 , A6 , A7 , A8 , A9 , A10,     \
      A11, A12, A13, A14, A15, A16, A17, A18, A19, A20,     \
      N, ...) N
    
    #define PP_REV_N() 20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0
    
    #define PP_CAT_BASIC_D(a, b) a ## b
    #define PP_CAT_BASIC(a, b) PP_CAT_BASIC_D(a, b)
    
    #define PP_CAT_LIST_1( tok) tok
    #define PP_CAT_LIST_2( tok, ...) PP_CAT_BASIC(tok, PP_CAT_LIST_1( __VA_ARGS__))
    #define PP_CAT_LIST_3( tok, ...) PP_CAT_BASIC(tok, PP_CAT_LIST_2( __VA_ARGS__))
    #define PP_CAT_LIST_4( tok, ...) PP_CAT_BASIC(tok, PP_CAT_LIST_3( __VA_ARGS__))
    #define PP_CAT_LIST_5( tok, ...) PP_CAT_BASIC(tok, PP_CAT_LIST_4( __VA_ARGS__))
    #define PP_CAT_LIST_6( tok, ...) PP_CAT_BASIC(tok, PP_CAT_LIST_5( __VA_ARGS__))
    #define PP_CAT_LIST_7( tok, ...) PP_CAT_BASIC(tok, PP_CAT_LIST_6( __VA_ARGS__))
    #define PP_CAT_LIST_8( tok, ...) PP_CAT_BASIC(tok, PP_CAT_LIST_7( __VA_ARGS__))
    #define PP_CAT_LIST_9( tok, ...) PP_CAT_BASIC(tok, PP_CAT_LIST_8( __VA_ARGS__))
    #define PP_CAT_LIST_10(tok, ...) PP_CAT_BASIC(tok, PP_CAT_LIST_9( __VA_ARGS__))
    #define PP_CAT_LIST_11(tok, ...) PP_CAT_BASIC(tok, PP_CAT_LIST_10(__VA_ARGS__))
    #define PP_CAT_LIST_12(tok, ...) PP_CAT_BASIC(tok, PP_CAT_LIST_11(__VA_ARGS__))
    #define PP_CAT_LIST_13(tok, ...) PP_CAT_BASIC(tok, PP_CAT_LIST_12(__VA_ARGS__))
    #define PP_CAT_LIST_14(tok, ...) PP_CAT_BASIC(tok, PP_CAT_LIST_13(__VA_ARGS__))
    #define PP_CAT_LIST_15(tok, ...) PP_CAT_BASIC(tok, PP_CAT_LIST_14(__VA_ARGS__))
    #define PP_CAT_LIST_16(tok, ...) PP_CAT_BASIC(tok, PP_CAT_LIST_15(__VA_ARGS__))
    #define PP_CAT_LIST_17(tok, ...) PP_CAT_BASIC(tok, PP_CAT_LIST_16(__VA_ARGS__))
    #define PP_CAT_LIST_18(tok, ...) PP_CAT_BASIC(tok, PP_CAT_LIST_17(__VA_ARGS__))
    #define PP_CAT_LIST_19(tok, ...) PP_CAT_BASIC(tok, PP_CAT_LIST_18(__VA_ARGS__))
    #define PP_CAT_LIST_20(tok, ...) PP_CAT_BASIC(tok, PP_CAT_LIST_19(__VA_ARGS__))
    
    #define PP_APPLY_CAT_LIST_D(n, ...) PP_CAT_LIST_ ## n(__VA_ARGS__)
    #define PP_APPLY_CAT_LIST(n, ...) PP_APPLY_CAT_LIST_D(n, __VA_ARGS__)
    
    #define PP_CAT_LIST(...) PP_APPLY_CAT_LIST(PP_NARG(__VA_ARGS__), __VA_ARGS__)
    
    PP_CAT_LIST(foo, bar, baz) // expandiert zu foobarbaz
    

    Das funktioniert in der Form für bis zu 20 Argumente, kann aber leicht erweitert werden. Das ist natürlich von Boost.Preprocessor inspiriert, wobei die diesen Mechanismus nicht anbieten, weil ihn (wie gesagt) nicht alle gängigen Compiler beherrschen. Wo ich den NARG-Trick her habe, weiß ich nicht mehr.



  • Netter Trick 🙂

    Da es wohl keine Lösung gibt, beliebig viele Argumente zu unterstützen (was ich mir bereits gedacht habe), werde ich wohl eine andere Lösung für mein Problem finden müssen.



  • wozu?

    Pi, du machst komische Dinge.



  • Ziehst DU echt in Erwägung, mehr als 20 Argumente zu haben?



  • volkard schrieb:

    Ziehst DU echt in Erwägung, mehr als 20 Argumente zu haben?

    und selbst wenn doch, dann kannst du ja nochmal 20 mehr einrichten...



  • << Perfektionist eben


Anmelden zum Antworten