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.