#include <iostream>

void typesafe_printf(const char* format) // Rekursionsende des Templates
{
    while (*format) {
        if (*format == '%') {
            throw std::runtime_error("Mehr Platzhalter als Parameter");
        }
        std::cout << *format++;
    }
};

template<typename T, typename... Rest>
void typesafe_printf(const char* format, T param, Rest... params) 
{
    while (*format) {
        if (*format == '%') {
            std::cout << param;
            format++;
            typesafe_printf(format, params...);
            return;
        }
        std::cout << *format++;
    }
};


#include <string>
#include <complex>

int main()
{
	typesafe_printf("Ein char: %, viele chars: %, ein string: %, ein int: %, ein double: %, ein complex: %",
	'a', "abc", std::string("blah"), 123, 123.123, std::complex<double>(20.2,2.5)
	);
}