B
Balog Pal
jacob navia said:Some people here argue that C++ is not overly complicated.
Care to give some reference to any of those people?
I am reading "C++ Templates, the complete Guide". There,
the authors say (page 15)
"The rules for this decision may become rather
complicated even without templates. ...
Every C++ programmer *must* know those rules but maybe
1% of them know the WHOLE set of rules because the human
mind is not adapted to absorbing tons of programming trivia.
Yeah, name lookup rules are complicated.
Yeah, no human being can recite them.
Yeah, we don' like it.
However, in practice this is not as big an issue as looks, as it has natural
mitigation.
It is:
- use names as they make sense
- overloads must be semantically equal
- avoid using directives on a namespace unless you really mean to drag in
everything and know all of it
You do just that, and don't need to care how many candidates are there and
which one got called if the set has more than one.
And those guidelines are good to follow regardless of name lookup rules...
(The dark side is unfortunately introduced via Koenig lookup that can drag
in stuff you are not aware exists... But it is not a 'complexity of C++'
issue, but a design flaw.)
THEN, it is obviously the task of the maintenance programmer
to debug all those cases where the byzantine rules go
completely in other direction that the poor programmer
intended, when some new code using indirectly those
overloaded functions is written, 2 years AFTER the original
programmer left.
Quite bad, that we have all kind of tools around, and they still fail to
address this very situation. I.e. MSVC shows you tooltips on mousing -- but
it is not based on compilation data even if it exists, and you're not told
what was picked up. Nor is is straightforward to see on a sensible listing.
The call graph of the function does not list the correct function (and btw
the internally involved invisible calls either), that would help so much.
The great majority of C++ programmers doesn't know *exactly*
what are they doing when do a simple thing like overloading
a function...
Now that is really BAD -- but blame the programmer, not the language.
Overload is a programmer-made decision and shall be a good one.
Is this really necessary?
What?
Overload is a powerful and needed feature. Without it you have a bigger
mess. And if your fellows misuse it, slap them.
I know way more cases where a programmer assigned the wrong value. Is it
grounds to get rid of assignment or claim it bad?
Now, look at this "concept" concept again. (Sorry but I find
no other way of saying it)
Behind it is the need to declare a set of types so that
template arguments can be checked by the compiler. OK.
But wasn't *inheritance* supposed to define this stuff?
Huh? Of course not. Care to explain how it comes into a picture?
Let's see a very simple concept, copyable. Used in many std:: collections
too.
That works fine for int, for char*, all POD types, etc... How you define it
via inheritance?
If you make a standard "super-class" that describes a
concept, wouldn't it be necessary just that your class
INHERITS from that super class to be cleanly checked
in the template argument list? Why is it necessary to
introduce YET ANOTHER huge construct?
Guess no, but show me on the above example...
just for reference the aim is to get:
std::vector<int> v1; //okay
std::vector<std::auto_ptr<int> > v2; // error: std::auto_ptr<int> fails is
not Copyable
Just as another thought: "concept" is meant for the template library
programmers. The people doing that correctly know how to use it and why it
is good. The rest of the public can ignore it entirely, just sit back and
enjoy the ride -- getting sensible checks and compile-time error flagging
when using the library. Making their life way less complicated than it is
now, when you get a 50-line message claiming it can't convert [20-line name]
to [similar 20-line name] just having std::map< std::string, std::string >
in a simple operation.