宏可变参数

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 或更早的时候可以这样做。