$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
From: David Abrahams (dave_at_[hidden])
Date: 2004-02-16 18:34:47
Gabriel Dos Reis <gdr_at_[hidden]> writes:
> David Abrahams <dave_at_[hidden]> writes:
>
> | Brian McNamara <lorgon_at_[hidden]> writes:
> | 
> | > Apologies ahead of time if I am putting words in anyone's mouth.
> | >
> | > I think Dave wants to imply that the class T in his example is not
> | > allowed to have a member named U according to Gaby's proposed rule.
> | 
> | That's what I thought he meant.
>
> But then, your remark about "would be horrible for generic program"
> is, ahem, puzzling.  You still did not explain why. 
Well, if my understanding of your proposed rule had been correct, it
would've meant that the names of a template's parameters would leak
out into requirements on its arguments (that they not have nested
members with that name).
> | > But this isn't how the rule would work; the way I see it, _these_:
> | >
> | >    struct Base { typedef int U; };
> | >
> | >    template <class U>
> | >    struct Derived : Base { };   // illegal
> | >
> | >    struct Derived2 : Base { 
> | >       template <class U>
> | >       void f(U u) {}            // illegal
> | >    };
> | >
> | > would be illegal ("the name U already has another meaning; choose
> | > another name for your template parameter"), whereas _these_:
> | >
> | >    struct Base { typedef int U; };
> | >
> | >    template <class B, class U>
> | >    struct Derived : B { };
> | >    /* ... Derived<Base> ... */
> | >
> | >    template <class B>
> | >    struct Derived2 : B { 
> | >       template <class U>
> | >       void f(U u) {}
> | >    };
> | >    /* ... Derived2<Base> ... */
> | >
> | > are both fine, since Base's "U" is hidden by virtue of being a dependent
> | > name.  There is still an issue of what happens if one of these last two
> | > classes issues a "using B::U" in its body; presumably then "U" ought to
> | > become outlawed as a valid template parameter name.
> | >
> | > Just my two cents here...
> | 
> | OK, I think I understand now.  I think it's a bizarre and inconsistent
> | rule.
>
> What is bizarre and inconsistent about it and is not with the other
> alternatives you care to name?  
As I expected my example below to demonstrate, I think it's
inconsistent with the way names from non-dependent base classes are
dealt with when masked by function parameter names.
Up till now, the only way that changing the name of a private member
could break a derived class (AFAIK) is if the member were virtual.
IIUC your proposed rule would add another one.
> This question is not rhetorical.  When you register strong opinons
> about a technical issue or throw in the air fashionable words like
> "generic programming", 
Generic Programming went out of style around here about 7 weeks ago.
It's so, like, 2003.
> the least that could be expected is that you provide technical
> explanation.
I just misunderstood your proposal, Gaby, and in that light I thought
the meaning behind my remarks to be "obvious".  
> |  Shall we outlaw:
> | 
> |   struct Base { static int x; };
> | 
> |   struct Derived : Base { 
> |      void f(int x) {}     // Horrors! we're masking a base class member!
>
> If you happen to pause a second and have look at the issue at hand,
> I'm confident that you'll see the difference between the case we're
> discussing and your example.
Of course I see the difference; they use different language features.
I also see the analogy.  I honestly don't see why the other case would
warrant a diagnostic, while this one doesn't.  Why is the difference
between a member template parameter and a function parameter
significant?
> |   };
> | 
> | Sorry for the sarcasm;
>
> And, I'm pretty sure you know sarcasm is not appropriate for
> tehcnical discussions.
Sorry, I'm not at my best.  Now returning to proper decorum.
-- Dave Abrahams Boost Consulting www.boost-consulting.com