On Saturday, September 22, 2012 09:49:04 Gor Gyolchanyan wrote:
> Can someone please tell me why the following code gives these
> errors?
>
> Error: class main.BirdZoo use of main.VertebrateZoo.take(Animal
> animal_) hidden by BirdZoo is deprecated
>
> Error: class main.ParrotZoo use of main.VertebrateZoo.take(Animal
> animal_) hidden by ParrotZoo is deprecated
>
> /// The code:
>
> class Animal { }
> class Vertebrate { }
> class Bird: Animal { }
> class Parrot: Bird { }
>
> class VertebrateZoo
> {
> void take(Animal animal_)
> {
> if(auto vertebrate = cast(Vertebrate)animal_)
> take(vertebrate);
> }
>
> abstract void take(Vertebrate vertebrate_);
> }
>
> class BirdZoo: VertebrateZoo
> {
> override void take(Vertebrate vertebrate_)
> {
> if(auto bird = cast(Bird)vertebrate_)
> take(bird);
> }
>
> abstract void take(Bird bird_);
> }
>
> class ParrotZoo: BirdZoo
> {
> override void take(Bird bird_)
> {
> if(auto parrot = cast(Parrot)bird_)
> take(parrot);
> }
>
> abstract void take(Parrot parrot_);
> }
The problem goes away if you add
alias VertebrateZoo.take take;
It also goes away if you change take in the derived class to take Animal.
My guess is that the problem is that the version of take which takes an Animal
is unavailable in the derived classes and is therefore "hidden." Any time that
you add an overload to a derived class which does not exactly override a
function in the base class, the base class overload is hidden in the derived
class. The normal fix for this is to alias the base class version in the
derived class. But why the compiler would now require that you do that, I
don't know. If that's the way that thnigs currently are, it starts to become a
bit odd that the base class functions aren't automatically available. IIRC,
the reason that they weren't before is so that you don't get cases where
you're not aware of what all of the overloads in a class are and end up with a
different function being called than you expected (so it's another one of the
function-hijacking prevention features), and I that still applies, so I guess
that that's why still have to do it. Still, it's weird.
TDPL may explain this. I don't know. I'd have to go digging. I'm 99.99%
certain that it explains the alias bit at least.
- Jonathan M Davis

On 9/22/12, Jonathan M Davis <jmdavisProg@gmx.com> wrote:
> But why the compiler would now require that you do that, I
> don't know. If that's the way that thnigs currently are, it starts to become
> a bit odd that the base class functions aren't automatically available.
http://dlang.org/hijack.html
There's a good reason why, consider:
class Foo
{
void foo(int) { }
}
class Bar : Foo
{
alias super.foo foo;
void foo(double) { }
}
void main()
{
auto bar = new Bar;
bar.foo(1); // calls Foo.foo
}
Now let's say Foo is a library class and you upgrade to a new version
of the library without realizing that the base method was removed:
class Foo
{
}
class Bar : Foo
{
alias super.foo foo; // error
void foo(double) { }
}
This now becomes a compile-time error. Without using the alias which
triggers the error the literal "1" would be implicitly converted to a
double and you'd end up invoking your own 'foo' method (which is no
longer an overload).

On 9/22/12, Andrej Mitrovic <andrej.mitrovich@gmail.com> wrote:
> I would prefer if "super.alias" meant to take overloads of all base
> classes into account.
Although this would be kind of counter-intuitive since 'super' already
means the direct base class.