
{I will not try to take this any further as it is - as Dave pointed out - totally OT for boost. Anyway, I am just forwarding this message from Daveed as requested (my fault, I CC'ed him :), I suggest we take any further discussion to clc++m where Daveed opened an appropriate thread some time ago and has a chance to participate directly. Daniel} From: David Vandevoorde <daveed@vandevoorde.com> Date: February 17, 2004 11:33:04 AM EST To: Gabriel Reis <gdr@integrable-solutions.net> Cc: Boost mailing list <boost@lists.boost.org> Subject: Re: [boost] Re: [OT] Hiding template parameters [was: FC++ Formal review is...] (I'm not on the Boost list. Gabriel: Apologies if you get this twice. I don't know if you're on the list. So to be sure, I left you on the recipients' list.) On Feb 17, 2004, at 6:29 AM, Gabriel Dos Reis wrote: [...]
Someone has characterized it as inconsistent without giving details as to why; all I'm saying is that, if one accepts the principle that "scopes nest", then the rule is a logical consequence, hence consistent with that principle.
You're making one more assumption: That template parameters really have their own full-fledged scope. I say that they shouldn't, just as function parameters don't.
Now, it might be that that logical consequence is unacceptable for some non-rational reasons, but that does not mean the consequence itself is inconsistent.
The current situation is IMO unacceptable for _rational_ reasons, no matter what the language- legalistic arguments for it may be.
| The POV is that | | class B { typename X }; | | template< typename X > class Y // 1 | : public B // 2 | { // 3 | ... | }; | | You think that template parameter X is declared in line 1, then hidden | by the base classes name introduced by line 2, thus non-accessible in | line 3, right? You think of the name scopes to nest in the same order, | do you?
What I think is: If we accept the principle that scopes should nest, then we should accept its logical consequences; if don't want to accept those logical consequences, then we should abandon the idea that scopes nest. Which one do you want to pick?
As mentioned above, I disagree that these are the only options. But even if you insist on thinking in those terms, then there it is still possible to come up with a mechanism that matches what most of us expect: Simply consider the base class scope to enclose the scope of the derived class parameters.
| This is a reasonable point of view, actually it's the current | language's interpretation of the topic, but it's not what I call | intuitive.
One major problem is what is defined "intuitive" and when "intuitive" is defeated by logic.
Oh please. I notice you posted to the thread "Opinion sought on name hiding issue" in comp.lang.c++.moderated. Except for you, the other dozen participants seem to have no problem on agreeing what is intuitive. See above for what I think is the flaw in your logic.
| While it's technically correct, it still feels wrong - at | least to me.
If you think it is wrong, while being consistent with first principle, then propose a a new first principle. The worst thing to do, I believe, is to introduce barnacled hacks that comes from nowhere.
| I see things more from a visibility-point-of-view. I
"scopes nest" is visitbility-point-of-view :-)
| can't see the base class' names at 2,
yet, you see the following
struct A { struct iterator { }; };
struct B : A { vodi f(iteraror); };
don't you? Or are you proposing that to be ill-formed?
I also see: struct A { typedef int I; }; struct B: A { typedef long I; }; struct C: B { I x; // B::I hides A::I }; Same with template parameters: They hide the homonyms in farther scopes.
We need general rules on which to decide, we don't need barnacled hacks that would appear "intuitive" at a moment when we don't have a working definition of "intuitive".
| I have to go back (that is, I | have to go one "scope" up) to see the names that are contained. This | makes me think of the lines 1 and 2 to be swapped wrt the names they | introduce into the scope of 3. To put it another way: The names of B | are not declared at 2, and that line 2 is also not like a using | declaration, although it might seem similar. | | If we use Dave's or my POV (and we are not alone ;), the advantages of | scopes can be used in this example, too. The advantage is a smaller | scope to search for a name: If you need to know what a name refers to, | you just look into the scopes from the inside (nearest scope), to the | outside. And it feels more natural to me if the scope of the template | parameters is closer than the scope of the class' base(s).
If the scope of the template-parameters should come after the scope of base classes -- that is the way I understand you "is closer" -- then one would not be able to use template-parameters in base classes.
And you cannot: You can only use them to _name_ base classes. In fact, now that I reflect on it, base classes are not really "enclosing scopes" of derived classes. You can simulate the lookup that way, but you could just as well say that inheritance is a sort of "base class using-directive" (which is how many compilers implement it).
If you don't agree with the "scopes nest" principle, then propose another principle, but please don't label it "intuitive" :-)
On the contrary: If that what Daniel's intuition says, he should label it as intuitive.
If I were to design a new programming language, I'm not sure I would just stick to "scopes nest", but here we're not designing a new programming language. IMO, one of the the worst things we can to the already complex C++ scope rules, is to come up with yet another special scope. At this point of complexity, following logical consequences is less evil than "intuitive" hacks where we don't have working definition of "intuitive".
You seem to imply that scope nesting is the only mechanism that directs C++ name lookup. That is not the case though (using directives, using declarations, and ADL don't work that way; inheritance doesn't really work that way either). Anyway, as many have pointed out, enabling sound C++ engineering requires the current situation to be fixed. Daveed