From my experience:
1) C++ is complicated enough to make it difficult to parse it whatsoever, not to mention parse it with good error recovery. For example, omitting ; at the end of class definition often makes it one with the following declaration/definition, thus yielding a cryptic message like:
New types cannot be defined in return type
instead of
Omitted ; after class definition
And the error is technically true! The problem is, the class def may be in one file and the error will appear in different one, which very often confuses beginner programmers (oh how many times did I fall for this one myself years ago!). But still, today's compilers try to be helpful - for example for quite some time g++ will give a hint ("did you forget a ;?") after the problem.
C++ is not perfect in most cases, but like 90% of them are quite simple to understand, and trivially simple once you know a bit better how C++ grammar looks like.
But there's a whole second level of errors out there...
2) Definitely the MOST sophiscated error messages a programmer may ever see are the errors related to templates and template instantiation. Such an error (just one!) often may span several screenfuls of text and an apprentice C++ programmer will panic at the very first sight. And the error underneath may be anything: even a simple typo in method name.
The problem here is simple: Templates in C++ are a programming language by themselves. No exagerrating here, they're proven to be Turing-complete :) And I believe that with the current C++, when you make a mistake with templates, there's NO reliable way for the compiler to guess "how this code is supposed to look like".
Then, the only thing the compiler can do is to say: I cannot instantiate template X with arguments A, B and C when C is a template instantiated with U, W, because C<U,W> cannot be passed as a parameter to X::foo(A,B,C<K,R>), et cetera, et cetera. Fill this with meaningful template names, meaningful method names and a lot of namespaces in between and you get lots of lines. Now, add "candidates are:" section to that and this gets LONG. Helpful and - with a little bit of patience and experience - readable, but LONG.
In fact, there was an attempt to solve this situation. It was called "concepts" and was meant to be included in the next C++ standard. Basically, a concept was to be something like a formal specificatation of the "interface" of a template.
With concepts, the above may be reduced to "the template T was declared to be instantiable with the second template parameter obeying the concept XYZ, and that template doesn't support XYZ, so I cannot instantiate T here".
But the problem is that "concepts", in order to be defined in a correct and useful manner, would be probably even more complicated than the template system itself. So they gave it up in C++0x...
So the answer is sad: The best thing we can do is to make a syntax colouring and formatting script for the compilers' error messages about templates. :)