获取可变参数宏参数列表中每个参数的类型?

问题描述 投票:0回答:1

我有一个这样的宏:

#define ptapply(pt, ret_type, identifier, ...) ((ret_type (*)()) pget(pt, identifier))(pt __VA_OPT__(,) __VA_ARGS__)

pget
返回一个
void *
,我将其转换为函数指针并调用。因为我不知道参数的数量及其类型,所以我必须使用
ret_type (*)()
,这在大多数情况下都很好,但如果其中一个参数具有
float
char
short
等类型或其他事情会变得混乱,因为 C 的默认升级规则将这些类型转换为
double
并且
int
。如果我能以某种方式在
typeof
中的每个参数上使用
__VA_ARGS__
,我可以将
void *
指针转换为确切的函数指针类型,但我不知道如何。有办法吗?

c c-preprocessor
1个回答
0
投票

很简单 - 在参数数量上重载宏并在每个宏元素上应用

__typeof__
。我喜欢以下超载风格:

#include <stdio.h>
void *pget(int, int) {
    return dprintf;
}

#define TYPES_1(a)       __typeof__(a)
#define TYPES_2(a, ...)  __typeof__(a), TYPES_1(__VA_ARGS__)
#define TYPES_3(a, ...)  __typeof__(a), TYPES_2(__VA_ARGS__)
#define TYPES_4(a, ...)  __typeof__(a), TYPES_3(__VA_ARGS__)
#define TYPES_N(_4,_3,_2,_1,_0,N,...)  TYPES_##N
#define TYPES(...)  \
    TYPES_N(0 __VA_OPT__(,) __VA_ARGS__,4,3,2,1)(__VA_ARGS__)

#define ptapply(pt, ret_type, identifier, ...) \
    ((ret_type (*)(__typeof__(pt), TYPES(__VA_ARGS__))) pget(pt, identifier))\
    (pt __VA_OPT__(,) __VA_ARGS__)

int main() {
    ptapply(1, int, 0, "%s %d\n", "Hello", 5);
}
© www.soinside.com 2019 - 2024. All rights reserved.