When the argument is that C++ has too many features that interact in unpredictable ways and are virtually impossible to get right, arguing that C++ is superior because it has more features is perhaps a fine argument in some hypothetical universe in which the primary objection to C++ is that it is missing features, but by failing to grapple with the points raised by the opposition in the real universe, you will fail to convince anybody. Everybody already knows all of these features, they're practically in the canonical Introduction to C++ pitch, and they still don't think C++ is great. Maybe you need to spend a bit more time listening more carefully to why; you certainly need to if you expect to talk anybody out of it.
You don't get a warning because the program is doing exactly what you asked it to do. You said a C with x = 0 is equal to 'true'. And you said a D with f = 0.0 is equal to 'true'. By transitivity of equality ...
Maybe it's just coming from a dynamic language, but it appears that you've overridden the bool operators to always return true. (except when you pass in 0 and 0.0) If you redefine how two structs of different kinds are compared, who is the compiler to say it's a problem?
In most dynamic languages 0 is false and anything else is true but it normally wouldn't use that information to coerce two values of different types to booleans before comparing them.
I'm only aware of php and javascript equating 0 to false. But at any rate in this case it's not equating 0 to false, it's comparing non-zero to zero and returning true. (as it should)
In C++0x you can make those operator bool() explicit. Shouldn't have been there in the first place, and you still have to learn the difference between explicit and non-explicit operators, but at least now there is a way of making things behave.
Even if they were explicit it wouldn't have "solved" his issue. Since he is using them in an if statement the C++ compiler would have considered that an explicit conversion anyway in C++0x mode.
I don't have a C++0x compiler handy, or I would test it, but I do believe explicit is only meant for cases such as this:
a + 1;
where a has a bool() operator that returns 1 or 0, in the old mode if there was no way to get a to be a number it would look at the operator bool() see that it returns a number and use that. Using explicit on the bool() operator would make that illegal and most likely a compiler error.
It's perfectly logical to use those functions when comparing them as booleans.
But it's confusing that they're being used as booleans at all. They're converted because it will let the types match even though the conversion doesn't make much sense.
Most of the points mentioned in that particular link pertains why both C and C++ are inferior to languages like LISP and Python which have garbage collectors, weak type system and the like.
The bitching about bad compile time errors has been mostly fixed in clang.
Then only _inconsistency_ (in the correct sense of the term) in C++ I am aware of is the unordered initialization of static objects. So if you have "class A { ... A () { } };" and have a "A foo;" declared somewhere with static linkage, it can be hard to pin down exactly _when_ that constructor will be called. It will be called before control is transferred to main, but you may want even finer control.
If you have noticed other inconsistencies I'd love to know.
> The bitching about bad compile time errors has been mostly fixed in clang.
Yes, IOW, it is a compiler problem, not a language problem. Because one particular compiler is horrible on error presentation doesn't mean that the language is bad.
> declared somewhere with static linkage, it can be hard to pin down exactly _when_ that constructor will be called.
The language doesn't define it on purpose. The language leaves it to be defined by the implementation because it goes a little beyond the purpose of the compiler. The compiler transforms C++ source into object code. You can have multiple objects linked together into a single binary, and this linkage is very platform and operating-system dependent. C++ is already horribly difficult to implement correctly; if the language were to define an order for static initialization, it would be stepping on the operating system domain, and make it even more difficult to implement on some systems.
often it's the implementation for certain platform that limits you, choices of what the C++ supports decides by the platform vendor - for example exceptions, rtti, or even up to date compiler.
another provblem arises due to the decoration, mangling of c++ symbols (while c externs do not have this problem), and sometimes this is problem even with two different versions of the same line of compiler
another one is the runtime incompabilities (exceptions again) and different compilers.
this problem is so bitchy, that if you have to develop plugin for maya, motion builder in c++, you have to use the same compiler the products were compiled with, which is not the case for a lot of the infrastructure, os out there...