可以通过宏参数的数目被重载? [英] Can macros be overloaded by number of arguments?
问题描述
如何这工作?如何才能C99 / C ++ 11可变参数的宏来实现扩展到不同的东西有多少参数传递给它的唯一依据?
How does this work? How can a C99/C++11 variadic macro be implemented to expand to different things on the sole basis of how many arguments are given to it?
推荐答案
要得到一个重载的宏,首先我们需要哪几个实现之间进行选择的宏。这部分不使用可变参数宏。然后,它一般认为它的参数的可变参数宏产生一个选择。堵漏参数计数到调度员产生过载宏。
To get an overloaded macro, first we need a macro which selects between several implementations. This part doesn't use a variadic macro. Then a variadic macro which generically counts its arguments produces a selector. Plugging the argument count into a dispatcher produces an overloaded macro.
警告:本系统无法分辨零和一的论点之间的区别,因为有是的没有任何参数之间以及单个空参数差异。他们都看起来像 MACRO()
。
Caveat: This system cannot tell the difference between zero and one arguments because there is no difference between no argument, and a single empty argument. They both look like MACRO()
.
要实现之间进行选择,使用宏连锁运营商提供了一系列函数宏。
To select between implementations, use the macro catenation operator with a series of function-like macros.
#define select( selector, ... ) impl ## _ ## selector( __VA_ARGS__ )
#define impl_1() meh
#define impl_2( abc, xyz ) # abc "wizza" xyz()
//etc
// usage: select( 1 ) => impl_1() => meh
// select( 2, huz, bar ) => impl_2( huzza, bar ) => "huz" "wizza" bar()
由于该 ##
运营商燮presses其参数宏扩展,最好把它包起来的另一个宏。
Because the ##
operator suppresses macro expansion of its arguments, it's better to wrap it in another macro.
#define CAT( A, B ) A ## B
#define SELECT( NAME, NUM ) CAT( NAME ## _, NUM )
要计算参数,使用 __ __ VA_ARGS
转向像这样的参数(这是聪明的一部分):
To count arguments, use __VA_ARGS__
to shift arguments like so (this is the clever part):
#define GET_COUNT( _1, _2, _3, _4, _5, _6 /* ad nauseam */, COUNT, ... ) COUNT
#define VA_SIZE( ... ) GET_COUNT( __VA_ARGS__, 6, 5, 4, 3, 2, 1 )
将其组合在一起:
Putting it together:
#define CAT( A, B ) A ## B
#define SELECT( NAME, NUM ) CAT( NAME ## _, NUM )
#define GET_COUNT( _1, _2, _3, _4, _5, _6 /* ad nauseam */, COUNT, ... ) COUNT
#define VA_SIZE( ... ) GET_COUNT( __VA_ARGS__, 6, 5, 4, 3, 2, 1 )
#define VA_SELECT( NAME, ... ) SELECT( NAME, VA_SIZE(__VA_ARGS__) )(__VA_ARGS__)
用法:
#define MY_OVERLOADED( ... ) VA_SELECT( MY_IMPL, __VA_ARGS__ )
#define MY_IMPL_1( X ) foo< X >
#define MY_IMPL_2( X, Y ) bar< X >( Y )
#define MY_IMPL_3( X, Y, Z ) bang_ ## X< Y >.Z()
这篇关于可以通过宏参数的数目被重载?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!