Советы по кодированию по вторникам — это короткие посты о различных лакомых кусочках, в основном из C++, но также и из других языков программирования, которые я использую. Вы также можете следить за хэштегом #TuesdayCodingTips на Mastodon и Linkedin.

Если вы хотите зарегистрировать имя файла и номер строки до C++20, вам нужно использовать подобные макросы __FILE__ и __LINE__. Чтобы их легко использовать, вы должны создать макрос-оболочку для ведения журнала, что обычно приводит к уродливому золоту макроса.

#include <iostream>
#include <format>

void log(
    const std::string& message,
    const std::string& fileName = __FILE__,
    unsigned lineNo = __LINE__)
{
    std::cout << std::format(
        "{}({}): {}\n",
        fileName,
        lineNo,
        message);
}

#define LOG(msg) log(msg, __FILE__, __LINE__)

int main()
{
    log("hello world");
    // logs: example.cpp(7): hello world
    // Note that __FILE__ and __LINE__ are expanded at their
    // position, not at the callsite
    LOG("hello world2");
    // logs: example.cpp(22): hello world2
    // Wrapping the call in another macro with explicit placement
    // of __FILE__ and __LINE__ makes them expand at the correct place
}

C++20 представляет std::source_location, обычный объект, который может быть сконструирован как значение по умолчанию параметра функции ведения журнала и передаваться по мере необходимости.

#include <iostream>
#include <source_location>
#include <format>

void log(
    const std::string& message,
    std::source_location location = std::source_location::current())
{
    std::cout << std::format(
        "{}({}) {}: {}\n",
        location.file_name(),
        location.line(),
        location.function_name(),
        message);
}

int main()
{
    log("hello world");
    // logs: example.cpp(19) int main(): hello world
}