Thread overview | |||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
November 09, 2012 delegate bug? | ||||
---|---|---|---|---|
| ||||
This code: import std.stdio; class A { void func() { writeln("A"); } } class B : A { override void func() { writeln("B"); } } void main() { A a = new A; B b = new B; auto dg = &a.func; dg(); dg.ptr = cast(void*)b; dg(); } outputs: A A but expected: A B |
November 09, 2012 Re: delegate bug? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jack Applegame | Windows dmd 2.060 |
November 09, 2012 Re: delegate bug? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jack Applegame | On 2012-11-09 14:36, Jack Applegame wrote: > This code: > > import std.stdio; > class A { > void func() { writeln("A"); } > } > class B : A { > override void func() { writeln("B"); } > } > void main() { > A a = new A; > B b = new B; > > auto dg = &a.func; > dg(); > > dg.ptr = cast(void*)b; > dg(); > } > > outputs: > A > A > > but expected: > A > B This is expected behavior. Delegates do not perform any dynamic dispatch. The method that is called is chosen when the delegate is created, i.e. "auto dg = &a.func;" You can workaround this by calling another method in "A" that will call the actual method you want to call, something like this: class A { void resolveVirtualCall () { func(); } } auto dg = &a.resolveVirtualCall; -- /Jacob Carlborg |
November 09, 2012 Re: delegate bug? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jack Applegame | Jack Applegame wrote:
> dg.ptr = cast(void*)b;
This changes the environment only. It does not change the function called on the``dg()'-request---and the function called does not depend on the environment.
But including a dependence on the environment may not change the output, because the compiler may instruct the executable to memoize the output.
Hint: casting is equivalent to exclaiming: "I know what I am doing. Therefore: shut up compiler!"
.manfred
|
November 09, 2012 Re: delegate bug? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Manfred Nowak | Ok. Then how to implement in D this С++ std::function feature? http://liveworkspace.org/code/01aa058901529f65cb9a3cc4ba605248 |
November 09, 2012 Re: delegate bug? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jack Applegame | Jack Applegame wrote: > Ok. Then how to implement in D this С++ std::function feature? > > http://liveworkspace.org/code/01aa058901529f65cb9a3cc4ba605248 That feature is among others defined here: http://en.cppreference.com/w/cpp/utility/functional/function As one might see it is a template, defined in a library. Therefore the first question is, wether D has a similar template in a library---and secondly: without such a template in a library: how to implement the base functionality in a non-generic case. Because this is a learning group and not a teaching group--and you did not report on your fruitless tries: go on. -manfred |
November 09, 2012 Re: delegate bug? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Manfred Nowak | > Because this is a learning group and not a teaching group--and you did > not report on your fruitless tries: go on. > > -manfred This is not only std::function feature. In C++ we can call member-function by combining potinter to object and pointer to function: http://liveworkspace.org/code/1fe3107cf3a311aa95cb9fc62b9117a7 I have no idea how to do somethink like that in D. |
November 09, 2012 Re: delegate bug? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Manfred Nowak | On 11/09/2012 10:30 AM, Manfred Nowak wrote: > Jack Applegame wrote: > >> Ok. Then how to implement in D this С++ std::function feature? >> >> http://liveworkspace.org/code/01aa058901529f65cb9a3cc4ba605248 > > That feature is among others defined here: > http://en.cppreference.com/w/cpp/utility/functional/function The following D program produces the same output as the C++ example there: import std.stdio : writeln; import std.functional : curry; struct Foo { int num; void print_add(int i) { writeln(num + i); } } void print_num(int i) { writeln(i); } void main() { // store a free function auto f_display = &print_num; f_display(-9); // store a lambda auto f_display_42 = { print_num(42); }; f_display_42(); // store a curried call alias curry!(print_num, 31337) f_display_31337; f_display_31337(); // store a call to a member function auto f_add_display = (Foo foo, int i) { return foo.print_add(i); }; auto foo = Foo(314159); f_add_display(foo, 1); } D has more features: // store a call to a member function on a particular object auto f_print_add_on_object = &foo.print_add; f_print_add_on_object(2); There is also std.functional.toDelegate: http://dlang.org/phobos/std_functional.html#toDelegate Ali |
November 09, 2012 Re: delegate bug? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | Ok. I will try to explain what exactly i need. import std.stdio; import std.stdio; class Figure { void draw(){} void erase(){} } class Circle : Figure { override void draw() { writeln("drawing circle"); } override void erase() { writeln("erasing circle"); } } class Square : Figure { override void draw() { writeln("drawing square"); } override void erase() { writeln("erasing square"); } } class Triangle : Figure { override void draw() { writeln("drawing triangle"); } override void erase() { writeln("erasing triangle"); } } void main() { Figure[] figures; createFigures(figures); doAction(figures, &Figure.draw); doAction(figures, &Figure.erase); } void doAction(Figure[] figures, void function() action) { foreach(Figure figure; figures) { // how to do action with figure??? } } void createFigures(ref Figure[] figures) { figures ~= new Circle; figures ~= new Square; figures ~= new Triangle; } |
November 09, 2012 Re: delegate bug? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jack Applegame | On 11/09/2012 07:49 PM, Jack Applegame wrote: >> Because this is a learning group and not a teaching group--and you did >> not report on your fruitless tries: go on. >> >> -manfred > This is not only std::function feature. In C++ we can call > member-function by combining potinter to object and pointer to function: > > http://liveworkspace.org/code/1fe3107cf3a311aa95cb9fc62b9117a7 > > I have no idea how to do somethink like that in D. > > auto memberFunctionPointer = function(X receiver, A arg0, B arg1, C arg2)=>receiver.memberFunction(arg0, arg1, arg2); This strategy is also the best way for a C++ compiler to implement a standard conformant member function pointer behind the scenes, so you lose nothing. |
Copyright © 1999-2021 by the D Language Foundation