Is it possible to pass a brace-enclosed initializer as a macro parameter?

后端 未结 1 1286
臣服心动
臣服心动 2020-12-29 04:52

I have a function that I call like this:

literal({1, 2});

I want to write a macro that expands to this statement, e.g.:

相关标签:
1条回答
  • 2020-12-29 05:03

    You can use __VA_ARGS__:

    #define MYMACRO(T,...) literal<T>(__VA_ARGS__);
    

    In case you have more parameters, you can use an indirection:

    #define UNWRAP(...) __VA_ARGS__
    #define MYMACRO(T,A) literal<T>(UNWRAP A);
    

    and now you can use

    MYMACRO( long[2], ({1, 2}) )
    

    Updated answer

    You could also, if you like, replace the curly brackets in the invocation of the macro with the round brackets:

    #define BRACED_INIT_LIST(...) {__VA_ARGS__}
    #define MYMACRO(T,A) literal<T>(BRACED_INIT_LIST A);
    

    and call

    MYMACRO( long[2], (1, 2) )
    

    which is IMHO consistent with typical macro-invocation-styles.

    Some words on your other questions: The preprocessor knows nothing about the language (C, C++, C++11) and hence should not care about the special meaning of symbols. It is tracking round brackets, but almost everything else is just tokens.

    I also think it's not an oversight from the standard committee as the focus should be on making the use of the preprocessor superfluous for most cases. Have you considered other (non-macro) techniques to implement MYMACRO? Also, work-arounds for the remaining use-cases (as shown above) are certainly possible.

    Finally, it is certainly not a bug in GCC as the compiler simply implements what the standard says.

    0 讨论(0)
提交回复
热议问题