Boost logo

Boost :

From: David Abrahams (dave_at_[hidden])
Date: 2004-02-17 10:50:09

I'm going to explain myself here so as not to leave Gaby hanging, but
then we should all take this branch of the thread off-line if we want
to pursue it. It is, as the subject line says, completely OT.

Gabriel Dos Reis <gdr_at_[hidden]> writes:

> David Abrahams <dave_at_[hidden]> writes:
> | > 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.
> But function parameters are not template parameters vice versa. And
> you should not expect them to behave the same without providing
> technical reasons why such expectations may take place.

Expectations are human things; their reasons aren't technical. I'll
try to explain anyway: I tend to assume (as do most people I think),
that similar things act similarly. Template parameters and function
parameters are the two kinds of parameters in C++.

> The fundamental difference between them is the places where they are
> declared. The scope of template-parameters *encloses* the template --
> that is why members of non-dependent bases hide them -- whereas member
> functions *are enclosed* by the scope (non-dependent) base classes
I can't parse that.

> -- which is why those function parameters can hide members in base
> classes.
> An action that would be consistent is to leave the current rule as is
> -- but some people been saying that that consistent behaviour goes
> against their intuition.
> | 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.
> No, that assessment it not true. Because name lookup happens before
> (overloading if applicable) and access checking applies, changing any
> name in the base (whether private or not is irrelevant) has the
> potential to break a derived class.
> class B { int X; }
> stryct Y { };
> struct D : B {
> Y y;
> };
> If you the name "X" in B to "Y"; you break D.

OK, you're right.

> I'm adding nothing here. It is a general issue. If you want to
> complain about it, fine.

Done already.

> But, that is not my invention and don't pretend I'm being innovative
> here or adding an unsual situation.

I'm not pretending that *you're* being innovative. I'm upset that the
current language definition allows such counter-intuitive semantics.
It still feels inconsistent with the rest of the language. Function
parameters are the only other instance of parameters in C++; it would
be better if parameters acted consistently.

> | > | 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?
> See a difference at the beginning of this message.

Your explanation isn't very satisfying. Of course I recognize that
these things are different, and so may have different rules. "They're
different because the language says so" isn't very useful when we're
talking about whether to change the language rules. I still don't
have a clue why they *should* be different.

Dave Abrahams
Boost Consulting

Boost list run by bdawes at, gregod at, cpdaniel at, john at