Quando si utilizza le macro variadic è necessario __VA_ARGS__
per espandere tutti gli argomenti. Il problema tuttavia è che quegli argomenti sono separati da virgola. Presumibilmente separa semplicemente gli argomenti da una chiamata di funzione, ma poiché le macro funzionano con solo testo puoi effettivamente usare __VA_ARGS__
anche in altri contesti, dove un elenco separato da virgola ha senso.
Il trucco è possibile utilizzare è quello di definire il proprio operatore di virgola per std::ostream
(il tipo di std::cout
). Per esempio:
#include<iostream>
#define LOG(...) std::cout , __VA_ARGS__ , std::endl
template <typename T>
std::ostream& operator,(std::ostream& out, const T& t) {
out << t;
return out;
}
//overloaded version to handle all those special std::endl and others...
std::ostream& operator,(std::ostream& out, std::ostream&(*f)(std::ostream&)) {
out << f;
return out;
}
int main() {
LOG("example","output","filler","text");
return 0;
}
Ora, l'invocazione LOG si espanderà a:
std::cout , "example" , "output" , "filler" , "text" , std::endl;
e le virgole invocherà le virgola operatori di overload.
Se non ti piace il sovraccarico di operator,
che inquina tutti i std::ostream
-s, puoi incapsulare std::cout
con la tua classe di logger speciale.
Perché? Perché? Perché? basta scrivere il codice –