Istnieje kilka implementacji funkcji printf szablonów variadic. Jednym z nich jest to:Variadic szablony i typy zabezpieczeń
void printf(const char* s) {
while (*s) {
if (*s == '%' && *++s != '%')
throw std::runtime_error("invalid format string: missing arguments");
std::cout << *s++;
}
}
template<typename T, typename... Args>
void printf(const char* s, const T& value, const Args&... args) {
while (*s) {
if (*s == '%' && *++s != '%') {
std::cout << value;
return printf(++s, args...);
}
std::cout << *s++;
}
throw std::runtime_error("extra arguments provided to printf");
}
i wszędzie jest powiedziane, że ta implementacja jest typu bezpieczne podczas normalnej C (przy zmiennej liczbie argumentów argumenty va_arg) nie jest.
Dlaczego tak jest? Co to znaczy być bezpiecznym w typie i jakie zalety ma to wdrożenie w porównaniu z printf va_arg?
Ta wersja nie dba w ogóle o flagi formatu, po prostu drukuje rzeczy za pośrednictwem operatorów strumieniowych. – Xeo
Jest to typ bezpieczny, ponieważ 'T' zawsze będzie typem faktycznie przekazanego parametru. Standardowy printf nie wie. –
Na marginesie, jest to okropna implementacja 'printf' przy wykonywaniu typów.Ignoruje i źle interpretuje specyfikatory formatu, a nawet nie obsługuje przenoszenia wartości tymczasowych! W skrócie, jest to funkcja "safe", ale nie jest to poprawna implementacja 'printf', pomimo swojej nazwy. Dobry "printf" działający pod kątem bezpieczeństwa będzie zachowywał się identycznie jak "printf", gdy będzie bezpieczny i nie powiedzie się niezdefiniowany, kiedy będzie w większości niebezpiecznych sytuacji. – Yakk