日志显示函数名

#include <iostream>
#include <cstdarg>
#include <cstdio>
#include <memory>

// LogImpl 只负责输出最终字符串(不再处理 format + va_list)
void LogImpl(const char* message) {
    std::cout << message << std::endl;
}

// Foo 负责格式化 + 注入 caller
void Foo(const char* caller, const char* format, ...) {
    va_list args;
    va_start(args, format);

    // 先估算缓冲区大小(C99+ 支持 vsnprintf 返回所需长度)
    int len = std::vsnprintf(nullptr, 0, format, args);
    if (len <= 0) {
        va_end(args);
        return;
    }

    // 分配足够空间
    std::unique_ptr<char[]> buffer(new char[len + 1 + 32]); // +32 给 "[caller] "

    // 再次调用 vsnprintf 格式化
    std::vsnprintf(buffer.get() + 0, len + 1, format, args);
    va_end(args);

    // 拼接 caller 前缀
    std::string fullMsg = std::string("[") + caller + "] " + std::string(buffer.get());

    // 调用 LogImpl
    LogImpl(fullMsg.c_str());
}

// 宏自动传入 caller
#define CALL_FOO(fmt, ...) Foo(__FUNCTION__, fmt, ##__VA_ARGS__)

// 使用示例
void Bar() {
    CALL_FOO("Error %d: %s", 404, "Not Found");
}

int main() {
    Bar(); // 输出: [Bar] Error 404: Not Found
    return 0;
}

  

posted @ 2026-05-12 17:02  leochan007  阅读(6)  评论(0)    收藏  举报