gpt4 book ai didi

c++ - 将变量名称作为字符串传递给具有默认参数的函数

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:19:22 24 4
gpt4 key购买 nike

假设有一个调试函数,这里简化为:

void DumpString(char* var, char* varname) {
printf("%s : '%s'\n", varname, var);
}

char str[10]="foobar";
DumpString(str, "str");

> str : foobar

让我们通过删除两次传递变量的不必要的无关要求来简化它,一次在引号中:

#define VARASSTR(v) #v

void DumpString(char* var) {
printf("%s : '%s'\n", VARASSTR(var), var);
}

char str[10]="foobar";
DumpString(str);

> var : foobar

糟糕!它使用局部变量名称而不是传入的名称。让我们尝试一种不同的(不太理想的)方法:

#define DumpStr(v) DumpString(v, #v)

void DumpString(char* var, char* varname) {
printf("%s : '%s'\n", varname, var);
}

char str[10]="foobar";
DumpStr(str);

> str : foobar

很好用。但是如果函数稍微复杂一点呢:

void DumpString(char* var, char* varname, int optionalvar=0) {
printf("%s : '%s'\n", varname, var);
printf("blah: %d", optionalvar);
}

无法重载宏,因此 DumpStr 将不起作用,我们已经排除了带有 VARASSTR 的版本。

如何处理(不求助于多个类似但名称不同的函数/宏)?

最佳答案

这是非标准的,但可以作为 GNU C 中的扩展使用:

#define DumpStr(v, ...) DumpString(v, #v, ##__VA_ARGS__)

在 GNU C 中,您不能向可变参数宏传递任何参数,并且“标记粘贴运算符”## 在逗号和空可变参数列表之间应用时不会产生任何结果(因此尾随逗号被抑制)。

在 Visual C++ 中,我认为标记粘贴运算符 ## 是不必要的(并且可能会破坏宏),因为 Visual C++ 会自动抑制出现在空可变参数列表之前的尾随逗号.

请注意,唯一使这个不标准的是有时传递一个空参数列表的愿望。可变参数宏在 C99 和 C++11 中都是标准化的。


编辑:这是一个不使用非标准功能的示例。您会明白为什么有些人真的非常希望标准中解决这类问题:

#define DUMPSTR_1(v) DumpString(v, #v)
#define DUMPSTR_2(v, opt) DumpString(v, #v, opt)
#define DUMPSTR_NARG(...) DUMPSTR_ARG_N(__VA_ARGS__, 4, 3, 2, 1, 0)
#define DUMPSTR_ARG_N(_1, _2, _3, _4, n, ...) n
#define DUMPSTR_NC(f, ...) f(__VA_ARGS__)
#define DUMPSTR_NB(nargs, ...) DUMPSTR_NC(DUMPSTR_ ## nargs, __VA_ARGS__)
#define DUMPSTR_NA(nargs, ...) DUMPSTR_NB(nargs, __VA_ARGS__)
#define DumpStr(...) DUMPSTR_NA(DUMPSTR_NARG(__VA_ARGS__), __VA_ARGS__)

可能有一些更简洁的方法可以做到这一点。但不是那么多。


编辑 2: 这是另一个不使用非标准功能的示例,由 R.. 提供

#define STRINGIFY_IMPL(s) #s
#define STRINGIFY(s) STRINGIFY_IMPL(s)
#define ARG1_IMPL(a, ...) a
#define ARG1(...) ARG1_IMPL(__VA_ARGS__, 0)
#define DumpStr(...) DumpString(STRINGIFY(ARG1(__VA_ARGS__)), __VA_ARGS__)

请注意,这需要更改 DumpString 的参数顺序,以便字符串化的函数名称是第一个参数。

关于c++ - 将变量名称作为字符串传递给具有默认参数的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9969490/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com