宏可变参数
Macro variadic argument
我有这个代码:
std::string format(const char *fmt, ...);
#define DEBUG(HANDLER, LEVEL, ...) LOG##LEVEL(HANDLER, format(__VA_ARGS__))
当我使用时有效:
DEBUG(handler, DEBUG, "var is %d\n", 15);
但是当我使用时它不起作用:
DEBUG(handler, DEBUG, "test");
如何检查只有一个参数还是多个参数?
我只需要使用 C++98 解决方案。
因为 __VA__ARGS__
在其他 C++98 编译器上可用(尽管是 C++11 feature),它有可能也有 __VA_OPT__
作为扩展:
您应该使用 __VA_OPT__(something)
(这是 C++20 的一项功能)使逗号仅在至少有一个参数时出现:
#define DEBUG(HANDLER, LEVEL, ...) LOG##LEVEL(HANDLER __VA_OPT__( format(__VA_ARGS__)))
或适合您情况的类似内容。
所以,我看了你的问题和你的代码,我意识到这可能是 臭名昭著的 XY 问题 的一个例子。
虽然你说,你想计算传递给宏的参数的数量,你想做的是编写调试消息,除了一个文字字符串外,没有任何其他参数示例中显示的调试消息。
DEBUG(handler, DEBUG, "test");
但这当然是可能的。为了测试它,我编写了以下代码。
std::string format(const char* fmt, ...) {
char buffer[256];
std::cout << __FUNCTION__ << std::endl;
va_list argList;
va_start(argList, fmt);
vsprintf(buffer, fmt, argList);
va_end(argList);
return std::string(buffer);
}
#define TRC(...) {\
std::cout << "MACRO!" << std::endl; \
std::cout << format(__VA_ARGS__);\
}
int main()
{
std::cout << "Hello World!" << std::endl;
const char *t = "b";
TRC("[%s] bla bla [%d]\n", t, 9);
TRC("test");
return 0;
}
产生输出,
Hello World!
MACRO!
format
[b] bla bla [9]
MACRO!
format
test
就像我之前在对你的问题的评论中提到的,我有 C++03
编译器,但我想这也适用于 C++98。
问题:
"How can I check if there's only one argument or more than one?"
无论你有一个参数还是多个参数,可变参数宏本身都没有问题。
但是如果你真的真的还想计算传入的参数数量,我不知道在 C++03
或更早的时候可以这样做。
我有这个代码:
std::string format(const char *fmt, ...);
#define DEBUG(HANDLER, LEVEL, ...) LOG##LEVEL(HANDLER, format(__VA_ARGS__))
当我使用时有效:
DEBUG(handler, DEBUG, "var is %d\n", 15);
但是当我使用时它不起作用:
DEBUG(handler, DEBUG, "test");
如何检查只有一个参数还是多个参数?
我只需要使用 C++98 解决方案。
因为 __VA__ARGS__
在其他 C++98 编译器上可用(尽管是 C++11 feature),它有可能也有 __VA_OPT__
作为扩展:
您应该使用 __VA_OPT__(something)
(这是 C++20 的一项功能)使逗号仅在至少有一个参数时出现:
#define DEBUG(HANDLER, LEVEL, ...) LOG##LEVEL(HANDLER __VA_OPT__( format(__VA_ARGS__)))
或适合您情况的类似内容。
所以,我看了你的问题和你的代码,我意识到这可能是 臭名昭著的 XY 问题 的一个例子。
虽然你说,你想计算传递给宏的参数的数量,你想做的是编写调试消息,除了一个文字字符串外,没有任何其他参数示例中显示的调试消息。
DEBUG(handler, DEBUG, "test");
但这当然是可能的。为了测试它,我编写了以下代码。
std::string format(const char* fmt, ...) {
char buffer[256];
std::cout << __FUNCTION__ << std::endl;
va_list argList;
va_start(argList, fmt);
vsprintf(buffer, fmt, argList);
va_end(argList);
return std::string(buffer);
}
#define TRC(...) {\
std::cout << "MACRO!" << std::endl; \
std::cout << format(__VA_ARGS__);\
}
int main()
{
std::cout << "Hello World!" << std::endl;
const char *t = "b";
TRC("[%s] bla bla [%d]\n", t, 9);
TRC("test");
return 0;
}
产生输出,
Hello World!
MACRO!
format
[b] bla bla [9]
MACRO!
format
test
就像我之前在对你的问题的评论中提到的,我有 C++03
编译器,但我想这也适用于 C++98。
问题:
"How can I check if there's only one argument or more than one?"
无论你有一个参数还是多个参数,可变参数宏本身都没有问题。
但是如果你真的真的还想计算传入的参数数量,我不知道在 C++03
或更早的时候可以这样做。