gpt4 book ai didi

c++ - 如何在各个参数中拆分#__VA_ARGS__

转载 作者:太空宇宙 更新时间:2023-11-04 08:48:25 42 4
gpt4 key购买 nike

在可变参数宏中,#__VA_ARGS__是所有参数的逗号分隔字符串(至少我用 gcc 和 clang 得到了这种行为)。有没有一种方法可以在不解析该字符串的情况下为各个参数创建一个字符串数组?

我正在使用下面的代码来创建调试输出,例如

DEBUG DUMP int main() AT demo.cc:53:
atan2(0.5, 0.5) => 0.785398
1 + 2 => 3
1 == 2 => false

来自代码如

debug_dump(atan2(0.5, 0.5), 1 + 2, 1 == 2);

但我目前的解决方案拆分了 #__VA_ARGS__使用 ad-hoc 词法分析器的字符串,当然无法解析带有模板参数的复杂情况,例如

debug_dump(std::pair<int,int>().first, 0 < 1);

因为没有简单的方法来区分哪个<和/或 >是模板参数的括号,是移位或比较操作的一部分。这是我当前代码的一个简短的独立示例(需要 C++11):

#include <utility>
#include <stdio.h>
#include <math.h>

void debug_dump_val_worker(int v) { fprintf(stderr, "%d", v); }
void debug_dump_val_worker(bool v) { fprintf(stderr, "%s", v ? "true" : "false"); }
void debug_dump_val_worker(double v) { fprintf(stderr, "%f", v); }
void debug_dump_args_worker(const char *) { }

template <typename T, typename ... Args>
void debug_dump_args_worker(const char *p, T first, Args ... args)
{
int next_p_state = 0;
const char *next_p = p;
while (*next_p && (next_p_state != 0 || *next_p != ',')) {
if (*next_p == '"')
do {
next_p++;
while (*next_p == '\\' && *(next_p + 1))
next_p += 2;
} while (*next_p && *next_p != '"');
if (*next_p == '\'') {
next_p++;
if (*next_p == '\\')
next_p++;
if (*next_p)
next_p++;
}
if (*next_p == '(' || *next_p == '[' || *next_p == '{')
next_p_state++;
if ((*next_p == ')' || *next_p == ']' || *next_p == '}') && next_p_state > 0)
next_p_state--;
next_p++;
}
fprintf(stderr, "\n\t%.*s => ", int (next_p - p), p);
if (*next_p == ',')
next_p++;
while (*next_p == ' ' || *next_p == '\t' || *next_p == '\r' || *next_p == '\n')
next_p++;
debug_dump_val_worker(first);
debug_dump_args_worker(next_p, args ...);
}

#define debug_dump(...) do { \
fprintf(stderr, "DEBUG DUMP %s AT %s:%d:", __PRETTY_FUNCTION__, __FILE__, __LINE__); \
debug_dump_args_worker(#__VA_ARGS__, __VA_ARGS__); \
fprintf(stderr, "\n"); \
} while (0)

int main()
{
debug_dump(atan2(0.5, 0.5), 1 + 2, 1 == 2);
debug_dump(std::pair<int,int>().first, 0 < 1);
return 0;
}

最佳答案

Yakk 所说的,预处理器不处理 <>匹配。

因此,如果您要这样做,那么您的代码需要比预处理器“更智能”。它需要完整的 C++ 编译器,一次 __VA_ARGS__扩展为对 debug_dump_args_worker 的调用的参数, 整理一下并认识到有两个参数,而不是三个。在更复杂的情况下,>>旨在关闭两个模板参数列表,直到 C++11 编译器才必须这样做,而不是将其视为不合适的移位运算符。所以实际上您的代码需要比 C++03 编译器“更智能”(也就是说,您需要上下文相关的标记化)。

我建议你最好的选择是放弃,并要求用户说:

debug_dump((std::pair<int,int>().first), 0 < 1);

相反。这是将模板参数放入单个宏参数的“通常”方法。您至少可以通过检查从字符串中提取的表达式的数量是否等于参数包的长度来捕获错误。如果用户忘记在模板参数列表周围放置括号,那么您会发现字符串中的表达式太多。

关于c++ - 如何在各个参数中拆分#__VA_ARGS__,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20679000/

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