我正在嘗試創建一個基本的記錄器。這是一個小例子。
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 模板知識。一個簡單的解決方案是放棄可變引數模板,只傳入一個字串,但我想看看這是否可行。有誰知道如何編譯?
謝謝。
uj5u.com熱心網友回復:
您不能在某些引數上使用 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://www.uj5u.com/ruanti/486134.html
上一篇:用字母表中的每個字符替換所有出現的字符的有效方法是什么?
下一篇:只有一個引數的模板特化
