Jump to page: 1 2
Thread overview
delegate bug?
Nov 09, 2012
Jack Applegame
Nov 09, 2012
Jack Applegame
Nov 09, 2012
Jacob Carlborg
Nov 09, 2012
Manfred Nowak
Nov 09, 2012
Jack Applegame
Nov 09, 2012
Manfred Nowak
Nov 09, 2012
Jack Applegame
Nov 09, 2012
Timon Gehr
Nov 09, 2012
Ali Çehreli
Nov 09, 2012
Jack Applegame
Nov 09, 2012
Timon Gehr
Nov 09, 2012
Jack Applegame
Nov 09, 2012
Jack Applegame
Nov 09, 2012
Jacob Carlborg
Nov 09, 2012
Timon Gehr
November 09, 2012
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
Windows dmd 2.060
November 09, 2012
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
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
Ok. Then how to implement in D this С++ std::function feature?

http://liveworkspace.org/code/01aa058901529f65cb9a3cc4ba605248
November 09, 2012
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
> 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
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
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
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.
« First   ‹ Prev
1 2