Re: How to Instantiate struct defined in template
On Sunday, 23 September 2012 at 04:51:31 UTC, Jonathan M Davis wrote: On Sunday, September 23, 2012 06:37:30 Craig Dillabaugh wrote: One question. Is there any way to get the function template to deduce the type of T from the vertices I pass, so that I can call: euclid_dist(v1, v2) ) instead of: euclid_dist!float(v1, v2) ); It should infer the types just fine as-is. Templated functions can pretty much always infer the template arguments from their function arguments. It's with types that that doesn't work (so a constructor requires template arguments, but a function does not). - Jonathan M Davis Yes, you are right. I thought I had tried it without the !float and it hadn't worked, but I guess not. Thanks again for all your help. Craig
Re: How to Instantiate struct defined in template
On Sunday, September 23, 2012 06:37:30 Craig Dillabaugh wrote: > One question. Is there any way to get the function template to > deduce the type of T from the vertices I pass, so that I can > call: > > euclid_dist(v1, v2) ) > > instead of: > > euclid_dist!float(v1, v2) ); It should infer the types just fine as-is. Templated functions can pretty much always infer the template arguments from their function arguments. It's with types that that doesn't work (so a constructor requires template arguments, but a function does not). - Jonathan M Davis
Re: How to Instantiate struct defined in template
On Sunday, 23 September 2012 at 04:03:28 UTC, Jonathan M Davis wrote: On Sunday, September 23, 2012 05:49:06 Craig Dillabaugh wrote: Hello, clip Before anything, I'd question why you declared vt at all. If all you're putting in it is a single struct, then just templatize the struct directly: struct Vertex(T) { ... } Now, it looks like you have a free function in there as well - euclid_dist - but there's no reason to put that in the same template. Just templatize it directly. Then you get T euclid_dist(T)(T a, T b) {...} And main ends up looking something like void main() { auto v1 = Vertex!float(0.0, 0.0); auto v2 = Vertex!float(2.0, 4.0); writefln("The distance between vertex 1 and vertex 2 is %s", euclid_dist(v1, v2)); } Thanks. I've switched my code to follow your suggestion. One thing there was a typo in my euclid_dist function, the code for it, and main now look like: T euclid_dist(T)(vertex!T a, vertex!T b) { T sum = 0; foreach( ref a_crd, ref b_crd; lockstep( a.coords, b.coords ) ) { sum += (a_crd - b_crd)*(a_crd - b_crd ); } return sqrt(sum); } int main(string argv[] ) { auto v1 = vertex!float(0.0,0.0); auto v2 = vertex!float(3.0,4.0); writeln("The distance between vertex 1 and vertex 2 is ", euclid_dist!float(v1, v2) ); return 0; } One question. Is there any way to get the function template to deduce the type of T from the vertices I pass, so that I can call: euclid_dist(v1, v2) ) instead of: euclid_dist!float(v1, v2) ); It's actually fairly to explicitly declare a template in D outside of eponymous templates. If you're dealing with a user-defined type or function, it almost always makes more sense to templatize them directly. Now, as for the exact error message, it's because the syntax that you're using to define v1 and v2 is illegal. You'd need to do either vt!float.vertex v1 = vt!float(0.0, 0.0); or preferrably. auto v1 = vt!float(0.0, 0.0); You can't construct the type on the left-hand side of the assignment operator like that. - Jonathan M Davis ,
Re: How to Instantiate struct defined in template
On Sunday, September 23, 2012 05:49:06 Craig Dillabaugh wrote: > Hello, > I am trying to figure out how templates work and tried to define > the > following template to define vertices of any dimension and > operations > on them. > > import std.stdio; > import std.random; > import std.range; > import std.conv; > import std.math; > > /* >* T must be one of the floating point types >* float, double, real _ I should be enforcing this. >*/ > template vt(T) > { > struct vertex { > this(T[] crds...) { > if( crds.length < 2 ) { > throw new.Exception("To small!"); > } else { > coords.length = crds.length; > foreach(ref v_coord, in_coord; lockstep(coords, crds)) > { > v_coord = in_coord; > } > } > } > @property T x() { return coords[0];} > @property T y() { return coords[1];} > @property T z() { return ( coords.length < 3 ? T.nan : > coords[2] ); } > } > > T euclid_dist(T a, T b) { > T sum = 0; > foreach( ref a_crd, ref b_crd; lockstep( a.coords, b.coords ) > ) { > sum += (a_crd - b_crd)*(a_crd - b_crd ); > } > return sqrt(sum); > } > } //End of template > > int main(string argv[] ) { > vt!(float).vertex v1(0.0,0.0); > vt!(float).vertex v2(3.0,4.0); > writefln("The distance between vertex 1 and vertex 2 is ", > vt!(float).euclid_dist(v1, v2) ); > } > > When I try to compile this I get the message: > > vertex.d(57): Error: found 'v1' when expecting ';' following > statement > vertex.d(58): Error: found 'v2' when expecting ';' following > statement > > Lines 57 and 58 are the first two lines in my main() function. I > can't figure out why, from the examples I've looked at I am using > the syntax properly, but am clearly missing something. > > Also, since I don't really know what I am doing any criticisms on > how I am defining the vertex template are welcome. Before anything, I'd question why you declared vt at all. If all you're putting in it is a single struct, then just templatize the struct directly: struct Vertex(T) { ... } Now, it looks like you have a free function in there as well - euclid_dist - but there's no reason to put that in the same template. Just templatize it directly. Then you get T euclid_dist(T)(T a, T b) {...} And main ends up looking something like void main() { auto v1 = Vertex!float(0.0, 0.0); auto v2 = Vertex!float(2.0, 4.0); writefln("The distance between vertex 1 and vertex 2 is %s", euclid_dist(v1, v2)); } It's actually fairly to explicitly declare a template in D outside of eponymous templates. If you're dealing with a user-defined type or function, it almost always makes more sense to templatize them directly. Now, as for the exact error message, it's because the syntax that you're using to define v1 and v2 is illegal. You'd need to do either vt!float.vertex v1 = vt!float(0.0, 0.0); or preferrably. auto v1 = vt!float(0.0, 0.0); You can't construct the type on the left-hand side of the assignment operator like that. - Jonathan M Davis
How to Instantiate struct defined in template
Hello, I am trying to figure out how templates work and tried to define the following template to define vertices of any dimension and operations on them. import std.stdio; import std.random; import std.range; import std.conv; import std.math; /* * T must be one of the floating point types * float, double, real _ I should be enforcing this. */ template vt(T) { struct vertex { this(T[] crds...) { if( crds.length < 2 ) { throw new.Exception("To small!"); } else { coords.length = crds.length; foreach(ref v_coord, in_coord; lockstep(coords, crds)) { v_coord = in_coord; } } } @property T x() { return coords[0];} @property T y() { return coords[1];} @property T z() { return ( coords.length < 3 ? T.nan : coords[2] ); } } T euclid_dist(T a, T b) { T sum = 0; foreach( ref a_crd, ref b_crd; lockstep( a.coords, b.coords ) ) { sum += (a_crd - b_crd)*(a_crd - b_crd ); } return sqrt(sum); } } //End of template int main(string argv[] ) { vt!(float).vertex v1(0.0,0.0); vt!(float).vertex v2(3.0,4.0); writefln("The distance between vertex 1 and vertex 2 is ", vt!(float).euclid_dist(v1, v2) ); } When I try to compile this I get the message: vertex.d(57): Error: found 'v1' when expecting ';' following statement vertex.d(58): Error: found 'v2' when expecting ';' following statement Lines 57 and 58 are the first two lines in my main() function. I can't figure out why, from the examples I've looked at I am using the syntax properly, but am clearly missing something. Also, since I don't really know what I am doing any criticisms on how I am defining the vertex template are welcome. Cheers, Craig
Re: Testing for template argument being result of takeExactly
On Sunday, September 23, 2012 02:57:36 bearophile wrote: > Jonathan M Davis: > > So, clearly I don't have the is expression right, and this is > > seriously pushing the edge of my knowledge of is expressions. > > So, any help would be appreciated. Thanks. > > I have done some tries, but I have failed, I am sorry :-) > The is() syntax is a part of D good to burn on a campfire. The power that it provides is useful if not outright necessary, but it could definitely use some improvements in the usability camp once you go beyond the basics. But I don't even know how you'd go about designing it so that it was more user friendly. > But takeExactly returns a Result struct defined inside it, so it > even possible for the is() syntax to work on this inner (hidden?) > type? Generally the idea of defining structs inside looks nice, > but seems a source for troubles. Yeah. Increasingly, it looks like Voldemort types are a bad idea as nice as they are in principle. But we have yet to reach the point where it's clear that we need to ditch them. We may yet get there though. - Jonathan M Davis
Re: Testing for template argument being result of takeExactly
Jonathan M Davis: So, clearly I don't have the is expression right, and this is seriously pushing the edge of my knowledge of is expressions. So, any help would be appreciated. Thanks. I have done some tries, but I have failed, I am sorry :-) The is() syntax is a part of D good to burn on a campfire. But takeExactly returns a Result struct defined inside it, so it even possible for the is() syntax to work on this inner (hidden?) type? Generally the idea of defining structs inside looks nice, but seems a source for troubles. Bye, bearophile
Testing for template argument being result of takeExactly
I'm trying to test whether a template argument is the type returned by takeExactly, and I haven't been able to sort out the template voodoo required yet. It would be a lot easier if I had a variable to work with, but I just have the type, and the fancy is expression required to pull it off is fancy enough that I haven't been able to sort it out yet. At present, I have this: import std.range; import std.stdio; template Hello(R) if(is(R r == U, V, V w, U = typeof(takeExactly(w, 1 { alias R Hello; } void main() { auto str = "hello"; auto t = takeExactly(str, 3); writeln(t); Hello!(typeof(t)) h = t; writeln(h); } I need Hello to instatiate if R is the type returned by takeExactly and fail to instantiate otherwise. At present, the code gives these compilation errors: q.d(15): Error: template instance Hello!(Result) Hello!(Result) does not match template declaration Hello(R) if (is(R r == U,V,V w,U = typeof(takeExactly(w,1 q.d(15): Error: Hello!(Result) is used as a type q.d(16): Error: template std.stdio.writeln does not match any function template declaration q.d(16): Error: template std.stdio.writeln(T...) cannot deduce template function from argument types !()(_error_) So, clearly I don't have the is expression right, and this is seriously pushing the edge of my knowledge of is expressions. So, any help would be appreciated. Thanks. - Jonathan M Davis
Re: system vs. execvp ?
Jonathan M Davis wrote: Peter Sommerfeld wrote: This works as expected: string cmd = "dmd src/xyz.d"; int i = system(cmd); But this not: string[] cmd; cmd ~= "src/xyz.d"; int i = execvp("dmd",cmd); Of course, dmd is in PATH (Win7). What is wrong here? Please elaborate on what doesn't work as expected. We can'thelp you if you don't tell us what's wrong. Well, system(cmd) compiles xyz.d and creates an executable. execvp(cmd) does call dmd but that behaves as if no arguments where given (Usage msg etc). No executables are created. system should run your command in a new process and return,whereas execvp will run it and never return, because the new process replaces your current one. I did not know that it does not return. Anyway, it should compile the args IMHO but it does not. Peter
Re: system vs. execvp ?
On 9/23/12, Jonathan M Davis wrote: > I'd be very surprised if you were correct about this. I was wrong, it's for a different reason: http://stackoverflow.com/questions/3027320/why-first-arg-to-execve-must-be-path-to-executable
Re: system vs. execvp ?
On Saturday, September 22, 2012 16:10:11 Jonathan M Davis wrote: > Now, looking at the docs for std.process.execvp, they seem to think that the > exec functions are going to return, but that's not what the man pages for > the C functions (which they're calling) say, nor is it how they behave. The problem with the documentation has been reported: http://d.puremagic.com/issues/show_bug.cgi?id=8708 - Jonathan M Davis
Re: system vs. execvp ?
On Sunday, September 23, 2012 01:12:34 Andrej Mitrovic wrote: > On 9/23/12, Peter Sommerfeld wrote: > > What is wrong here? > > string[] cmd; > cmd ~= "dmd"; > cmd ~= "src/xyz.d"; > int i = execvp("dmd",cmd); > > 1st arg should always be the app name, even though apps typically > ignore/skip the first arg. Are you sure about that? That seems pretty messed up if that's the case. Yes, the first element in the argument list that main gets is the name of the program, but it's pretty messed up if any of the exec* functions require that you give the program name as the first argument rather than it being appropriately added by that program before its main is called. I'd be very surprised if you were correct about this. - Jonathan M Davis
Re: system vs. execvp ?
On 9/23/12, Peter Sommerfeld wrote: > What is wrong here? string[] cmd; cmd ~= "dmd"; cmd ~= "src/xyz.d"; int i = execvp("dmd",cmd); 1st arg should always be the app name, even though apps typically ignore/skip the first arg.
Re: system vs. execvp ?
On Sunday, September 23, 2012 00:53:48 Peter Sommerfeld wrote: > Hi! > > This works as expected: > >string cmd = "dmd src/xyz.d"; >int i = system(cmd); > > But this not: > >string[] cmd; >cmd ~= "src/xyz.d"; >int i = execvp("dmd",cmd); > > Of course, dmd is in PATH (Win7). > > What is wrong here? Please elaborate on what doesn't work as expected. We can't help you if you don't tell us what's wrong. system should run your command in a new process and return, whereas execvp will run it and never return, because the new process replaces your current one. Now, looking at the docs for std.process.execvp, they seem to think that the exec functions are going to return, but that's not what the man pages for the C functions (which they're calling) say, nor is it how they behave. Maybe that's your problem? http://linux.die.net/man/3/exec http://msdn.microsoft.com/en-us/library/3xw6zy53.aspx - Jonathan M Davis
system vs. execvp ?
Hi! This works as expected: string cmd = "dmd src/xyz.d"; int i = system(cmd); But this not: string[] cmd; cmd ~= "src/xyz.d"; int i = execvp("dmd",cmd); Of course, dmd is in PATH (Win7). What is wrong here? tia Peter
Re: object.error: Privileged Instruction
On 09/22/2012 11:33 AM, simendsjo wrote: > assert(false, "aoeu"); // with message, object.error: Privileged Yep, Dvorak keyboard rules! ;) Ali
Re: object.error: Privileged Instruction
On Saturday, September 22, 2012 21:19:27 Maxim Fomin wrote: > Privilege instruction is an assembly instruction which can be > executed only at a certain executive process context, typically > os kernel. AFAIK assert(false) was claimed to be implemented by > dmd as a halt instruction, which is privileged one. > > However, compiled code shows that dmd generates int 3 instruction > for assert(false) statement and 61_6F_65_75 which is binary > representation of "aoeu" for assert(false, "aoeu") statement and > the latter is interpreted as privileged i/o instruction. It's a normal assertion without -release. With -release, it's a halt instruction on Linux but IIRC it's something slightly different (albeit similar) on Windows, though it might be halt there too. - Jonathan M Davis
Re: object.error: Privileged Instruction
Privilege instruction is an assembly instruction which can be executed only at a certain executive process context, typically os kernel. AFAIK assert(false) was claimed to be implemented by dmd as a halt instruction, which is privileged one. However, compiled code shows that dmd generates int 3 instruction for assert(false) statement and 61_6F_65_75 which is binary representation of "aoeu" for assert(false, "aoeu") statement and the latter is interpreted as privileged i/o instruction.
object.error: Privileged Instruction
What does the message in the subject mean? Here's a testcase (tested on dmd 2.060 on win7 32-bit): import core.exception; import core.runtime; // comment out this, and no stacktrace is printed void myAssertHandler(string file, size_t line, string msg = null) { } static this() { setAssertHandler(&myAssertHandler); f(); } version(unittest) { void f() { //assert(false); // without message, object.error: Breakpoint assert(false, "aoeu"); // with message, object.error: Privileged Instruction } }
Re: Passing associative array to another thread
On 22.9.2012 13:50, Johannes Pfau wrote: >> 1. Declare it as "shared" > There's also __gshared. Yup, that works. Thanks
Re: Passing associative array to another thread
Am Sat, 22 Sep 2012 12:30:30 +0200 schrieb Jacob Carlborg : > On 2012-09-22 11:24, Martin Drasar wrote: > > > thanks for the hint. Making it shared sounds a bit fishy to me. My > > intention is to pass some read only data, that are in fact thread > > local and there is no real need to make them shared. > > The whole point of thread local data is that it's only accessible > from a single thread. If you want to share it with another thread you > have, as far as I know, there options: > > 1. Declare it as "shared" There's also __gshared. > 2. Declare it as "immutable" > 3. Make a copy, i.e. serialize the data
Re: Passing associative array to another thread
On 22.9.2012 13:19, Jonathan M Davis wrote: > The problem with immutable is probably due to this bug: > > http://d.puremagic.com/issues/show_bug.cgi?id=5538 > > And casting to shared probably won't work due to this bug: > > http://d.puremagic.com/issues/show_bug.cgi?id=6585 > > std.variant needs quite a bit of work done to it, and it's causing problems > with std.concurrency is this case. In the interim, I suspect that just about > the only way to get an AA across threads is to just make it shared and not > use > std.concurrency at all, as undesirable as that may be. Your serialization > suggestion would probably be the only other choice, though that would require > something like Orange, as Phobos doesn't have such facilities. > > - Jonathan M Davis Hi Jonathan, I will work around the AA. As I have said, it is used only to pass name-value pairs. So no need to ditch the entire std.concurrency because of that. Martin
Re: Passing associative array to another thread
On Saturday, September 22, 2012 12:30:30 Jacob Carlborg wrote: > Looking at your original example I don't understand why the immutable aa > won't work. That's the whole point of immutable, it's safe to share > among threads. It's probably a bug somewhere. I think someone else can > answer these questions better than me. The problem with immutable is probably due to this bug: http://d.puremagic.com/issues/show_bug.cgi?id=5538 And casting to shared probably won't work due to this bug: http://d.puremagic.com/issues/show_bug.cgi?id=6585 std.variant needs quite a bit of work done to it, and it's causing problems with std.concurrency is this case. In the interim, I suspect that just about the only way to get an AA across threads is to just make it shared and not use std.concurrency at all, as undesirable as that may be. Your serialization suggestion would probably be the only other choice, though that would require something like Orange, as Phobos doesn't have such facilities. - Jonathan M Davis
Re: Passing associative array to another thread
On 2012-09-22 11:24, Martin Drasar wrote: thanks for the hint. Making it shared sounds a bit fishy to me. My intention is to pass some read only data, that are in fact thread local and there is no real need to make them shared. The whole point of thread local data is that it's only accessible from a single thread. If you want to share it with another thread you have, as far as I know, there options: 1. Declare it as "shared" 2. Declare it as "immutable" 3. Make a copy, i.e. serialize the data The (de)serialization is possible but the overhead seems a bit pointless. I will alter the code to use something else than AAs if there is no other way. The data I am trying to pass is in fact just name-value pairs. I have tried to use Tuples, but I have hit another batch of problems. One was related to issue #5783, but another made me really scratch my head... Looking at your original example I don't understand why the immutable aa won't work. That's the whole point of immutable, it's safe to share among threads. It's probably a bug somewhere. I think someone else can answer these questions better than me. -- /Jacob Carlborg
Re: Passing associative array to another thread
On 21.9.2012 19:01, Jacob Carlborg wrote: > Perhaps declaring the associative array as "shared". An alternative > would be to serialize the aa, pass it to another thread, and deserialize > it. That would though create a copy. Hi Jacob, thanks for the hint. Making it shared sounds a bit fishy to me. My intention is to pass some read only data, that are in fact thread local and there is no real need to make them shared. The (de)serialization is possible but the overhead seems a bit pointless. I will alter the code to use something else than AAs if there is no other way. The data I am trying to pass is in fact just name-value pairs. I have tried to use Tuples, but I have hit another batch of problems. One was related to issue #5783, but another made me really scratch my head... This compiles ok: struct S { Tuple!int i; } This does not: struct S { Tuple!int i; SysTime t; } Error: function std.typecons.Tuple!(int).Tuple.opEquals!(const(Tuple!(int))).opEquals (const(Tuple!(int)) rhs) is not callable using argument types (const(Tuple!(int))) const This looks a lot like the #5783, but I don't understand, why it only shows up with the SysTime in place... Martin
Re: how is this considered hiding methods?
On 9/22/12, Andrej Mitrovic 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.
Re: how is this considered hiding methods?
On 9/22/12, Andrej Mitrovic wrote: > Now let's say the Doo clas removes the meth overload and the alias: Sorry that should be "the Bar class".
Re: how is this considered hiding methods?
On 9/22/12, Andrej Mitrovic wrote: > using the alias But I do think this can be further improved in the language. Take this for example: import std.stdio; class Foo { void meth(double) { writeln("Foo.meth"); } } class Bar : Foo { alias super.meth meth; void meth(int) { writeln("Bar.meth"); } } class Doo : Bar { alias super.meth meth; void meth(long) { writeln("Doo.meth"); } } void main() { auto doo = new Doo; doo.meth(1); // calls Bar.meth } Now let's say the Doo clas removes the meth overload and the alias: class Foo { void meth(double) { writeln("Foo.meth"); } } class Bar : Foo { // gone } class Doo : Bar { alias super.meth meth; void meth(long) { writeln("Doo.meth"); } } void main() { auto doo = new Doo; doo.meth(1); // now calls Doo.meth } We might have wanted the "super alias" in Doo to only work against the Bar base class so the compiler can notify us if Doo.meth is removed. The language doesn't have a way to warn us of this. I would prefer if "super.alias" meant to take overloads of all base classes into account and that we could use "ClassName.alias" to only import the overload set of a specific base class. That way this would trigger a CT error: class Foo { void meth(double) { writeln("Foo.meth"); } } class Bar : Foo { } class Doo : Bar { alias Bar.meth meth; // error: no overload set in Bar void meth(long) { writeln("Doo.meth"); } }
Re: how is this considered hiding methods?
On 9/22/12, Jonathan M Davis 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).
Re: how is this considered hiding methods?
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
Re: how is this considered hiding methods?
On Saturday, 22 September 2012 at 07:48:02 UTC, 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_); } I figured it out: class BirdZoo: VertebrateZoo { alias VertebrateZoo.take take; override void take(Vertebrate vertebrate_) { if(auto bird = cast(Bird)vertebrate_) take(bird); } abstract void take(Bird bird_); } class ParrotZoo: BirdZoo { alias BirdZoo.take take; override void take(Bird bird_) { if(auto parrot = cast(Parrot)bird_) take(parrot); } abstract void take(Parrot parrot_); }
how is this considered hiding methods?
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_); }