我正在尝试创建一个基本的记录器。下面是一个小例子。
template<typename ...str>
struct log {
log(
str &&...args,
const char *file = __builtin_FILE(),
const char *func = __builtin_FUNCTION(),
const size_t line = __builtin_LINE()
) {
std::cout << "[" << file << "] [" << func << "] [" << line << "] ";
((std::cout << args << " "), ...);
std::cout << std::endl;
}
};
template<typename ...str>
log(str &&...args) -> log<str ...>;我希望能够接收调用者的信息以及可变数量的参数。使用上面的示例,我可以创建这样一个实例。
log inst("THIS WORKS", "ASD", "ASD");
>>> [.../main.cpp] [main] [10] THIS WORKS ASD ASD我还希望能够指定日志记录级别。这就是麻烦开始的地方。假设我有下面的日志记录级别,我想让它成为记录器的模板参数。以下是我认为这是如何运作的。
enum logging_level {
INFO,
};
template<logging_level level, typename ...str>
struct log {
...
};
template<logging_level level, typename ...str>
log(str &&...args) -> log<level, str ...>;
log<INFO> inst("THIS DOESN'T WORK", "ASD", "ASD");这里我遇到的错误是,参数被传递到默认参数中,而不是变量参数。
>>> error: invalid conversion from ‘const char*’ to ‘size_t’ {aka ‘long unsigned int’} [-fpermissive]
>>> 33 | log<INFO> inst("THIS DOESN'T WORK", "ASD", "ASD");
>>> | ^~~~~
>>> | |
>>> | const char*这远远超出了我的C++模板知识。一个简单的解决方案是抛弃变量模板,只传递一个字符串,但我想看看这是否有效。有人知道如何编译吗?
谢谢。
发布于 2022-06-05 18:04:08
不能在某些参数上使用CTAD,而不能在其他参数上使用CTAD。通过使用标记分派,您可以使用类似的语法。为此,您需要将日志级别的规范移到参数列表中。
注意,在下面的示例中,我使用std::source_location (C++20)独立于编译器:
enum class LogLevel
{
INFO
};
template<LogLevel logLevel>
struct LogLevelInfoTag {
constexpr operator LogLevel()
{
return logLevel;
}
};
constinit LogLevelInfoTag<LogLevel::INFO> INFO;
template<LogLevel logLevel, typename ...str>
struct log {
log(
LogLevelInfoTag<logLevel>,
str &&...args,
std::source_location location = std::source_location::current()
) {
std::cout << "[" << location.file_name() << "] [" << location.function_name() << "] [" << location.line() << "] ";
((std::cout << args << " "), ...);
std::cout << std::endl;
}
};
template<LogLevel logLevel, typename ...str>
log(LogLevelInfoTag<logLevel>, str &&...args) -> log<logLevel, str ...>;
// log<INFO> inst("THIS DOESN'T WORK", "ASD", "ASD"); // (desired syntax)
log inst(INFO, "THIS DOESN'T WORK", "ASD", "ASD");https://stackoverflow.com/questions/72509526
复制相似问题