Boost logo

Boost :

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

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