Question about typeof(this)

Don nospam at nospam.com
Tue Sep 14 00:28:25 PDT 2010


Jacob Carlborg wrote:
> On 2010-09-10 16:53, Pelle wrote:
>> On 09/10/2010 03:20 PM, Jacob Carlborg wrote:
>>> On 2010-09-07 22:32, Don wrote:
>>>> Jacob Carlborg wrote:
>>>>> On 2010-09-07 17:29, Don wrote:
>>>>>> Jacob Carlborg wrote:
>>>>>>> I'm reading http://www.digitalmars.com/d/2.0/declaration.html#Typeof
>>>>>>> where it says:
>>>>>>>
>>>>>>> "typeof(this) will generate the type of what this would be in a
>>>>>>> non-static member function, even if not in a member function. "
>>>>>>>
>>>>>>> From that I got the impression that the code below would print the
>>>>>>> same result, but it doesn't. It prints:
>>>>>>>
>>>>>>> main.Bar
>>>>>>> main.Foo
>>>>>>>
>>>>>>> instead of:
>>>>>>>
>>>>>>> main.Foo
>>>>>>> main.Foo
>>>>>>>
>>>>>>> Is this a bug or have I misunderstood the docs?
>>>>>>
>>>>>> typeof(this) gives the *compile-time* type of this. Inside Bar, it 
>>>>>> has
>>>>>> to return 'Bar'.
>>>>>> typeid(this) gives the *runtime* type of this. So it can work that
>>>>>> it's
>>>>>> Bar is actually a Foo.
>>>>>
>>>>> I know that typeof(this) is a compile time expression but in this case
>>>>> I think the compiler has all the necessary information at compile
>>>>> time. Note that I'm not calling "method" on a base class reference,
>>>>> I'm calling it on the static type "Foo". In this case I think
>>>>> typeof(this) would resolve to the type of the receiver, i.e. the type
>>>>> of"foo".
>>>>
>>>> Even though in this instance it could work out which derived class is
>>>> being used, it's not allowed to use that information while compiling
>>>> method(). There is only ONE function method(), and it has to work for
>>>> Bar, and all classes derived from Bar.
>>>
>>> I think Scala can handle this problem, the following text is a snippet
>>> from a paper called "Scalable Component Abstractions" (link at the
>>> bottom), page 4 "Type selection and singleton types":
>>>
>>> class C {
>>> protected var x = 0;
>>> def incr: this.type = { x = x + 1; this }
>>> }
>>>
>>> class D extends C {
>>> def decr: this.type = { x = x - 1; this }
>>> }
>>>
>>> "Then we can chain calls to the incr and decr method, as in
>>>
>>> val d = new D; d.incr.decr;
>>>
>>> Without the singleton type this.type, this would not have
>>> been possible, since d.incr would be of type C, which does
>>> not have a decr member. In that sense, this.type is similar
>>> to (covariant uses of ) Kim Bruce's mytype construct [5]."
>>>
>>> I'm not very familiar with Scala but the above code example seems to
>>> work as I want typeof(this) to work.
>>>
>>> http://www.scala-lang.org/sites/default/files/odersky/ScalableComponent.pdf 
>>>
>>>
>>>
>>
>> You can do this in D, but the syntax is clumsy. And it uses templates.
>>
>> class C {
>> int x;
>> T incr(this T)() {
>> x += 1;
>> return cast(T)this; // clumsy, but always works (?)
>> }
>> }
>> class D : C {
>> T decr(this T)() {
>> x -= 1;
>> return cast(T)this;
>> }
>> }
>>
>> void main() {
>> D d = new D;
>> d.decr.incr.decr.incr.incr;
>> writeln(d.x);
>>
>> }
> 
> I've done some testing with this template parameters and it actually 
> works as I want it to, but I don't understand why it has to be a 
> template. Both templates and typeof are resolved at compile time so I 
> don't understand why it can't work with typeof. I have this example now:
> 
> module main;
> 
> import std.stdio;
> 
> class Base
> {
>     void foo (this T) ()
>     {
>         writeln(T.stringof);
>         writeln(typeof(this).stringof);
>     }
> }
> 
> class Foo : Base { }
> 
> void main()
> {
>     auto foo = new Foo;
>     foo.foo;
> }
> 
> It will print:
> 
> Foo
> Base
> 
> To me this template parameters look unnecessary, typeof should be able 
> to handle this. In the above "foo" method I think T should be equal to 
> typeof(this).
> 
There are only two ways to have the behaviour you want:
(1) make it a template, so that the function is duplicated for every 
derived class (that's what this solution is doing); OR
(2) use runtime type information.

Both of these have unacceptable consequences in general.


More information about the Digitalmars-d-learn mailing list