C++: Prevent method from expanding too early when passed as argument

35 views Asked by At

I attempt to write a basic logger that should pass any message to the shell and a log file (for now, both write to std::out) using std::vformat. For that, i created a wrapper log_message():

template <typename ...P>
void log_message(std::string_view format, P&& ...params) {
    m_do_colors = false;
    std::cout << "Writing to file, flag is " << m_do_colors << std::endl;
    log_message_to_file(format, params...);

    m_do_colors = true;
    std::cout << "Writing to shell, flag is " << m_do_colors << std::endl;
    log_message_to_shell(format, params...);
};

template <typename ...P>
void log_message_to_shell(std::string_view format, P&& ...params) {
    std::string msg = std::vformat(format, std::make_format_args(params...));
    std::cout << msg << std::endl;
};

template <typename ...P>
void log_message_to_file(Severity severity, std::string_view format, P&& ...params) {
    std::string msg = std::vformat(format, std::make_format_args(params...));
    std::cout << msg << std::endl;
};

I also have a function that puts ANSI color tags around a string:

bool m_do_colors = true;

std::string color_str(std::string str, int color) {
    std::cout << "colorizing string: " << m_do_colors << std::endl;
    if ( m_do_colors == true ) {
        return std::format("\033[0;{}m{}\033[0;m", color, str);
    } else {
        return str;
    };
};

the purpose of the m_do_color variable should be to "disable" colorizing a string whenever the message is passed to the file output, but "enable" colors when output is shell.

An example for a use case with logger.h:

#pragma once
#include <string>
#include <iostream>
#include <utility>
#include <format>

class Logger {
  /** (((stuff from above))) **/
}

and main.cpp:

#include "logger.h"

int main() {
    Logger log;
    log.log_message(log.INFO, "This is a {}", log.color_str("Test", 45));
    return 0;
}

what is printed is

colorizing string: 1
Writing to file, flag is 0
This is a Test
Writing to shell, flag is 1
This is a Test 

with "Test" having coloured background both times. The output idicates that all arguments of the log_message() function are expanded before the function's body is expanded.

What I want to get is this:

Writing to file, flag is 0
colorizing string: 0
This is a Test
Writing to shell, flag is 1
colorizing string: 1
This is a Test 

with only the second "Test" being coloured.

How can I prevent the color_str() method from "expanding too early"? Is there a way to tell the compiler that the arguments of log_message() should only be expanded inside its body, not beforehand?

I already tried with "regular" std::format() and also passing the arguments on with std::forward, but the result is always the same.

0

There are 0 answers