Some of it is also the fault of the compilers for being too explicit in their default error messages. You get that horrible output because string is really a typedef to "basic_string<char>" and basic_string takes two more template arguments with defaults. But why is the compiler resolving the typedef in the error message by default? At least let it be "std::map<std::string, std::string, std::less<std::string>, std::allocator<std::pair<std::string const, std::string> > >" instead of that inscrutable noise.
And if you really need to provide the information that "std::string" is "std::basic_string<char, std::char_traits<char>, std::allocator<char> >" then put it on a separate line in the output, once, instead of repeating it internally within every recursive template instantiation.