Предисловие
В этом посте будут найдены два решения, одно с использованием C ++ 03, а другое C ++ 11.
Это сложно (т.е. вам нужно написатьмного кода), если вы хотите истинное время компиляции , если , что гарантировано , не будет никаких накладных расходов во время выполнения, как раньше (без скачков функций и т. д.).
Однако это возможно, хотя поддерживать код будет довольно утомительно, если вы захотите добавить к нему другую опцию (в C ++ 03).Я бы порекомендовал вам проверить следующие решения.
Решение на C ++ 03
Ваш компилятор должен быть достаточно умен, чтобы оптимизировать любой вызов на LogHelper<+NONE>
, хотяесли вы просто ищете более читаемый код и не получаете прирост производительности, этот синтаксис довольно приятный.
enum LoggerType {
NONE =0,
DATE = (1<<0),
TIME = (1<<1),
PERCENT = (1<<2)
};
template<int> void LogHelper (std::string&);
template<> inline void LogHelper<+NONE> (std::string&) {}
template<> inline void LogHelper<+DATE> (std::string& s) {s += "1970-01-01 ";}
template<> inline void LogHelper<+TIME> (std::string& s) {s += "12:01:01 ";}
template<> inline void LogHelper<+PERCENT> (std::string& s) {s += "42% ";}
template<int LOG_FLAG = NONE>
struct Logger {
static void log (std::string const& description) {
std::string s1;
LogHelper<DATE & LOG_FLAG> (s1);
LogHelper<TIME & LOG_FLAG> (s1);
LogHelper<PERCENT & LOG_FLAG> (s1);
std::cerr.width (25);
std::cerr << s1 << " >> " << description << std::endl;
}
};
...
int
main (int argc, char * argv[]) {
Logger<DATE|TIME|PERCENT> foo_log;
Logger<TIME> time_log;
Logger<> no_log;
time_log.log ("log objects initialized!");
foo_log .log ("using foo_log");
no_log .log ("about to terminate application");
}
output
12:01:01 >> log objects initialized!
1970-01-01 12:01:01 42% >> using foo_log
>> about to terminate application
Решение с использованием шаблонов Variadic (C ++ 11)
enum LoggerType {
NONE, PERCENT, DATE, TIME
};
template<LoggerType T = NONE, LoggerType ... Next>
std::string LogHelper () {
return LogHelper<T> () + "; " + LogHelper<Next...> ();
}
template<> std::string LogHelper<NONE> () {return ""; }
template<> std::string LogHelper<DATE> () {return "1970-01-01";}
template<> std::string LogHelper<TIME> () {return "00:01:42";}
template<> std::string LogHelper<PERCENT> () {return "42%";}
template<LoggerType ... Types>
struct Logger {
static void log (std::string const& description) {
std::cerr.width (25);
std::cerr << LogHelper<Types...> ();
std::cerr << " >> " << description;
std::cerr << std::endl;
}
};
...
int
main (int argc, char * argv[]) {
Logger<DATE,TIME,PERCENT> foo_log;
Logger<TIME> time_log;
Logger<> no_log;
time_log.log ("log objects initialized!");
foo_log .log ("using foo_log");
no_log .log ("about to terminate application");
}
вывод
00:01:42 >> log objects initialized!
1970-01-01; 00:01:42; 42% >> using foo_log
>> about to terminate application