This gets rid of the us-less function:
template<typename A>
void forward(A const&...) const{}
We converted struct Printer into a function call printValue().
template<typename A>
std::ostream& printValue(std::ostream& s,
std::string const& prefix,
Formatter const& format,
A const& value) const
This means the compiler could do argument type deduction. So the call could be simplified:
// from
Printer<decltype(std::get<I>(arguments))>(s, prefixString[I], formater[I], std::get<I>(arguments))...
// too
printValue(s, prefixString[I], formater[I], std::get<I>(arguments))...
But now that it is a function (rather than a class) it has accesses to the members. So we don't actually need to pass all those parameters. So we can simplify even more:
// too
template<std::size_t I>
std::ostream& printValue(std::ostream& s) const
// Now the call is simply
printValue<I>(s)...