我正在设计一个记录器。我会格式化它。我做了一个设计,我会预先确定格式字符串,然后将这些数据保存在一个元组中并将其打印到日志中。
下面的代码现在可以运行,但我希望它在我注释掉的部分中运行。 所以,根据我设置的默认参数,如果没有给出参数,我希望它使用默认参数。
注意:我希望这些过程在编译时进行。
#include <iostream>
#include <tuple>
#include <memory>
#include <type_traits>
class MyLogger {
public:
template<typename... Args>
void Log(const char* format, Args... args) {
printf(format, args...);
printf("\n");
}
};
static inline std::unique_ptr<MyLogger> logger = std::make_unique<MyLogger>();
template<typename FMT, typename... Args>
struct LogLineDef {
LogLineDef(Args... args) : values(args...) {}
std::tuple<Args...> values;
};
constexpr char FMT1[] = "A:%d, B:%d, C:%d, D:%f ";
using L1 = LogLineDef<std::integral_constant<const char*, FMT1>, int, int, int, float>;
template<typename FMT, typename... Args>
void log_helper(const char* message, const LogLineDef<FMT, Args...>& logger_line_def) {
std::apply([message](const auto&... args) {
logger->Log((FMT::value + std::string(message)).c_str(), args...);
}, logger_line_def.values);
}
#define LOG(logger_line_def, message, ...) log_helper(message, logger_line_def, ##__VA_ARGS__)
int main() {
LOG(L1(1, 2, 3, 4.f), "error");
//LOG(L1(1, 2, 3), "error"); // should be legal according to default value
//LOG(L1(1, 2), "error"); // should be legal according to default value
}