Puede probar las características de los tipos.
Por ejemplo, int
puede contener un valor negativo, mientras que char*
no puede. Así que si ((typeof(param))-1) < 0
, param
está sin firmar:
if (((typeof(param))-1) < 0) {
do_something_with_int();
} else {
do_something_with_char_p();
}
El compilador optimiza obviamente esto.
probar aquí: http://ideone.com/et0v1
Esto sería aún más fácil si los tipos tenían diferentes tamaños.Por ejemplo, si desea escribir una macro genérico que puede manejar diferentes tamaños de caracteres:
if (sizeof(param) == sizeof(char)) {
/* ... */
} else if (sizeof(param) == sizeof(char16_t)) {
/* ... */
} else if (sizeof(param) == sizeof(char32_t)) {
/* ... */
} else {
assert("incompatible type" && 0);
}
GCC tiene una función incorporada __builtin_types_compatible_p()
que puede comprobar la compatibilidad tipos:
if (__builtin_types_compatible_p(typeof(param), int)) {
func_int(param);
} else if (__builtin_types_compatible_p(typeof(param), char*)) {
func_string(param);
}
Pruébalo aquí: http://ideone.com/lEmYE
Puede poner esto en una macro para lograr lo que está tratando de hacer:
#define FUNC(param) ({ \
if (__builtin_types_compatible_p(typeof(param), int)) { \
func_int(param); \
} else if (__builtin_types_compatible_p(typeof(param), char*)) { \
func_string(param); \
} \
})
(El ({...})
es un GCC's statement expression, permite que un grupo de declaraciones sea un valor r.
El __builtin_choose_expr()
integrado puede elegir la expresión para compilar. Con __builtin_types_compatible_p esto permite desencadenar un error en tiempo de compilación si el tipo de parámetro no es compatible tanto con int
y char*
: (compilando somehting no válida en este caso)
#define FUNC(param) \
__builtin_choose_expr(__builtin_types_compatible_p(typeof(param), int) \
, func_int(param) \
, __builtin_choose_expr(__builtin_types_compatible_p(typeof(param), char*) \
, func_string(param) \
, /* The void expression results in a compile-time error \
when assigning the result to something. */ \
((void)0) \
) \
)
Esto es en realidad un ejemplo ligeramente modificado a partir de __builtin_choose_expr docs.
Incluso si esto fuera posible, sería fugly. C no fue diseñado para eso. Use estructuras y uniones, incluso puede obtener el despacho en tiempo de ejecución de esa manera. –