Re: Rationale for two C++ features
sean_in_raleigh@yahoo.com wrote:
I'm curious what the rationale was for two
oddities in C++.
I'll give you my understanding, but these may be flawed. Hopefully
someone will correct me if I'm wrong.
1) Why did the standards committee choose
the oddball no-extension names for the standard
headers (<string>, e.g.)? I can understand them wanting to
emphasize that an included entity is not necessarily
a file, but they say "header file" throughout the standard,
and calling it something like "string.hpp" would not have implied
that it was necessarily a file.
Originally, the headers were iostream.h, string.h, etc. When the
standard library got moved into the std namespace, the most
straightforward way to avoid breaking backward compatibility was to have
new headers #include the old headers within the new namespace:
/* <iostream> */
namespace std {
#include <iostream.h>
}
Anywhere, I rather prefer the shorter header names. They're easier to
read, and easier to type.
2) Why was the following use of the conditional operator
made illegal?
class B { };
class D1 : public B { };
class D2 : public B { };
int main(int argc, char **argv) {
B *p1 = argc == 1 ? new D1() : new B();
B *p2 = argc == 1 ? new D1() : new D2();
}
In the code above, the p1 assignment is legal,
while the p2 assignment is not (according to
the standard's expr.cond.5, and the Comeau
and GNU compilers I tried). Why not just
treat it as the following:
B *p2;
if (argc == 1)
p2 = new D1();
else
p2 = new D2();
The ternary operator constitutes an expression, and (unlike the if/else
tree) must have a single static type. In the case you've shown, there
is a clear an obvious choice; however, that may not always be the case.
If neither sub-expression has a type convertible to the other's, then
finding the right super-type may be non-trivial. For example:
struct A { }
struct B { };
struct D1: B { };
struct D2: B { };
int main(int argc, char** argv[]) {
D1 d1;
D2 d2;
A const* const a = argc > 2 ? &d1 : &d2;
B const* const b = argc > 2 ? &d1 : &d2;
return 0;
}