Boost logo

Boost :

From: Daniel Frey (daniel.frey_at_[hidden])
Date: 2004-02-17 11:54:23


{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_at_[hidden]>
Date: February 17, 2004 11:33:04 AM EST
To: Gabriel Reis <gdr_at_[hidden]>
Cc: Boost mailing list <boost_at_[hidden]>
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


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk