Disclaimer: This should be titled “Things about C++ that suck,” but “C++ sucks” is a much better search term.
1. Too many ways to write identical things.
This is a language smell. Ideally, there should be one way to write things, not multiple. For instance, there are at least 9 ways to create an alias to an unsigned long int:
typedef unsigned long int foo;
typedef unsigned long foo;
typedef long unsigned int foo;
unsigned long int typedef foo;
unsigned long typedef foo;
long unsigned int typedef foo;
using foo = unsigned long int;
using foo = unsigned long;
using foo = long unsigned int;
The fact that ‘typename’ and ‘class’ can be used in template declarations is rather silly, especially since ‘class’ is only enforced for template templates.
Having both ‘struct’ and ‘class’ is a waste of keywords. I prefer ‘struct’ as defaulting to public gets used much more often then defaulting to private.
Trigraphs are another issue. I can’t see any use for them anymore other than backwards compatibility.
2. Templates are an unholy mess.
Templates are great for their intended purpose: generic types. Attempting to do metaprogramming with them is torture.
The 3 most obvious things are ‘typename’, ‘template’, and ‘this’ used inside of templates. They’re not incredibly hard to use, rather they feel inconsistent with the rest of the language. Major compilers seem to do fine without them – perhaps I’m missing something but it really doesn’t seem necessarily to have them anymore.
Inconsistency is a real problem for templates. Specializations are a real issue here – some things you can, some things you can’t, and others you are severely restricted on. And why can’t parameters be evaluated in specializations?
Metafunctions and types aren’t very type safe. There’s no language feature for them, and so you’re left coming up with your own standards. Also, while tmp practically requires a recursive approach, doing so often causes compiler crashes as everything must be evaluated at compile time – even branches that cannot be reached.
3. The standard library is part of the language
What I mean by this is that many things cannot be done without using the standard library. Some language features even require it, the most notable being certain exceptions, ‘typeof’ and the new initializer lists.
The thing that really bothers me is that perhaps the most used container, std::vector, involves magic. The reason for this is that there’s no standard way to resize allocated memory. realloc() somewhat works, although it doesn’t work for non-pod data types. It blows my mind that the committee has been rejecting improvements to memory allocation for so many years. If 2 functions were added, realloc_nocopy and alloc_size, then I would be very very happy, as (somewhat) efficient memory allocation could finally be possible!
Well that’s all I’m going to write about. There are quite a few other sucky parts of C++, but those 3 are the ones that bother me the most.