The bizarre world of typeof()

Denis Koroskin 2korden at gmail.com
Mon Oct 26 06:54:44 PDT 2009


On Mon, 26 Oct 2009 16:38:42 +0300, Kagamin <spam at here.lot> wrote:

> Lars T. Kyllingstad Wrote:
>
>> I'm saying that the compiler should
>> give an error when it encounters the expression &Foo.bar
> why?

This is somewhat invalid expression without a context:

class Foo
{
     int bar() { return 42; }
}

auto dg1 = &Foo.bar; // fine?
int x = dg1(); // fine, too?

But sometimes context is implicit:

class Derived : Foo
{
     auto get()
     {
         return &Foo.bar; // context is this and is implicit
     }
}

auto dg2 = (new Derived()).get();
int y = dg2(); // okay



Also sometimes you need a function and don't care about context:

void delegate(int x) dg;
dg.funcptr = &Foo.bar;
dg.ptr = new Foo();

int z = dg(); // also fine

So &Foo.bar should stay.

> Lars T. Kyllingstad Wrote:
>
>>      // This one fails with the following hilarious message:
>>      // Error: static assert  (is(real function() == function)) is false
>>      static assert (is (typeof(&Foo.bar) == function));
>
> Failure is valid, compiler just can't show member function types  
> correctly.

That's a correct behavior. &Foo.bar returns a *function*, not a delegate  
(because of a lack of context), and  no type information is associated  
with it.

Well, it's could return a delegate (with a null context), too, but then  
reassigning delegate.funcptr would be less obvious:

dg.funcptr = (&Foo.bar).funcptr;


And it won't save you from invoking a delegate with a missing context:

int delegate() dg = &Foo.bar;
dg(); // oops!



More information about the Digitalmars-d mailing list