C/C++ 可变宏函数重载

C/C++ Variadic Macro Function Overloading

我正在尝试构建一个简单的 C++ 记录器用于学习目的,但我似乎陷入了以下问题。假设我有一个包含以下两个函数的名称空间:

namespace l {
    void _p(const char* file, const int line, int vl, const char* fmt, ...) {
        printf("%d:%s:%d: ", vl, file, line);
        va_list __args;
        va_start(__args, fmt);
        vfprintf(stdout, fmt, __args);
        printf("\n");
        va_end(__args);
    }
    void _p(const char* file, const int line, const char* fmt, ...) {
        printf("%s:%d: ", file, line);
        va_list __args;
        va_start(__args, fmt);
        vfprintf(stdout, fmt, __args);
        printf("\n");
        va_end(__args);
    }
}

主要功能如下:

int main(int argc, char** argv)
{
    l::_p(__FILE__, __LINE__, 12, "%s", "Hello World!");
    l::_p(__FILE__, __LINE__, "%s", "Hello World!");
    return 0;
}

我想要的是一个宏,当用户键入:l::p(12, "%s", "Hello World!"); 时,它会在编译时被 l::_p(__FILE__, __LINE__, 12, "%s", "Hello World!"); 替换。同样,当用户键入 l::p("%s", "Hello World!"); 时,它会在编译时被 l::_p(__FILE__, __LINE__, "%s", "Hello World!"); 替换

使用日志记录宏

#define LOG(...) l::_p(__FILE__, __LINE__, __VA_ARGS__)

void f(int i) {
    LOG(12, "%d", i);
    LOG("%d", i);
}

what I would like to have is a macro such that when the user types: l::p(12, "%s", "Hello World!"); it would be replaced by l::_p(__FILE__, __LINE__, 12, "%s", "Hello World!"); at compile time.

当然可以:

#define p(...)  _p(__FILE__, __LINE__, __VA_ARGS__)

宏是在预处理阶段处理的,此时编译器不知道任何复杂的东西,比如命名空间。所以这样的宏可能会让不知情的程序员感到困惑,他们稍后会尝试定义一个名为 p 的函数或调用一个名为 p.

的函数指针

最好在 C++ 中使用带有宏的类似流的接口,而不是像 BOOST_LOG 那样,例如,(从 C++20 开始你可以使用 source_location)。