Really? Very little? Finely tuned fabric?
Is diamond inheritance really part of that fabric? And NULL?
C++ is old and has only accumulated, never lost. When I think "finely tuned fabric", I think of Rust, which has the fortune of decades of learning. C++ piled on rvalues and move semantics. Rust is the one that "tuned" its design.
I'm not dissing C++; it's a true veteran, and has witnessed entire languages rise and fall. But let's be honest: the design of C++ is (as one would expect for a decades-old language) organic, not "finely tuned".
Diamond inheritance isn't a problem in C++ as each inheritance path is followed separately. A small price to pay to enjoy the power of multiple inheritance.
And NULL?
NULL is deprecated since C++ 11 in favor of nullptr.
C++ is old and has only accumulated, never lost.
You may want to have a look at the latest standards.
Pedantically, it's discouraged, not deprecated. NULL is a preprocessor constant defined in so many places, often in contradictory ways. There's no practical way for the C++ standards to deprecate it.
Compiler and analysis tools vendors could (and should) provide warnings when NULL is used when nullptr is more appropriate (which is always IMO).
Seeing C++ codebases using 0 for pointers instead of NULL was already a sign how up to date the respective programmers were with C++'s best practices.
I wouldn't call C++'s design organic, just severly constrained by backwards compatibility. It is finely tuned, but the results are not even close to an ideal that didn't consider C. Finely tuned doesn't imply perfection.
When I try to be objective about it though, I'd say you are glorifying too much and skipping on the darker sides of it. You and me probably now exactly how to avoid those and that's also exactly one of the reasons why for us C++ is all utter greatness. But when I see inferior, dangerous, ugly, waiting-for-UB code produced by others I realize it's not all that great. Or maybe still great - after all you could blame their lack of knowledge instead of C++ - but I really wouldn't use terms like finely tuned or extremely logcical. Seriously, I've used the language for like 10 years and it still occurs to me that I see a C++ question and corresponding answer on SO which completely baffle me because I had no clue about that particular implementation detail. There aren't many languages like that. Here's one just from today: http://stackoverflow.com/questions/39422188/difference-betwe... granted I would never write that stuff, but also I really couldn't tell 100% sure how 'const int& x = 4;' at classlevel is supposed to behave.
for (std::vector<std::pair<int, double>>::const_iterator it = v.begin(); it != v.end(); ++it) {
foo(*it);
}
The above used to be the recommended way to write a loop until C++11, and was supposedly superior to for (int i = 0; i < v.size(); ++i) {
foo(v[i]);
}
which was considered to be error prone and unsafe. But now things are much nicer and you can write for (auto x : v) {
foo(x);
}
Looks so much better. Clearly "auto" is a win for C++ programmers. But wait, it turns out that there's actually a bunch of different ways of writing the auto keyword that have subtly different semantics. You can write "auto", but you can also use every possible combination of "auto" with "const", "&" and "&&". So things like "auto&&" or "const auto&" are also perfectly valid and sometimes preferable to simple old "auto".Let's put aside the fact that you can't explain the difference between "*", "&" and "&&" to a C programmer without them bursting out laughing. Why does auto have six different variants? Isn't this emblematic of how C++ is evolving?
The fact that C11 made the security Annex optional, is a sign how much the C committee values writing safe code.
usually you'd use for(const auto& : v) though
template<class T,class...>class C{C<T*const,T,C>a;C<T,C>b;};C<int>c;
(c) Marc Aldorasi