I need an Easy example to understand Alias This

Ali Çehreli acehreli at yahoo.com
Tue Jul 7 01:19:00 UTC 2020


On 7/6/20 5:44 PM, Marcone wrote:
> On Tuesday, 7 July 2020 at 00:42:40 UTC, Ali Çehreli wrote:
>> On 7/6/20 5:35 PM, Marcone wrote:
>>> Hi, I study Dlang for one year, and I can't understand alias this. I 
>>> need an Easy example to understand Alias This.
>>
>> Is the following example useful?
>>
>>   http://ddili.org/ders/d.en/alias_this.html
>>
>> Ali
> 
> I can't undestand it. I need a simple example.

I find the example of converting two integers to double to be a simple 
example of 'alias this'. (If it's not simple, then there is another 
example later.)

So, allow me to change the name of the struct. :) Let's say we have a 
Money class that stores dollars and cents as two separate members. This 
class also has a member function that returns the amount as double:

struct Money {
   long dollars;
   long cents;

   double value() const {
     return double(cents) / 100 + dollars;
   }
}

unittest {
   assert(Money(10, 50).value == 10.5);
}

void main() {
}

So far so good: We can get the value by calling value().

*If* this is a type where conversion to double should be automatic, then 
calling value() all over the place might be considered cumbersome and 
too wordy. If that's true, we may want to get the value of this type 
automatically as double. For example, we may want to be able to call the 
following function with Money:

void foo(double d) {
   // ...
}

void main() {
   foo(Money(20, 50));  // <-- Compilation error
}

Currently the code fails to compile because Money is not 'double'. 
(Note: Arguably, Money is not a type that should be converted to double 
automatically, but again, I find this example simple.)

'alias this' allows a type to be converted to a specific type 
automatically. For example, if we want to convert Money objects 
automatically to 'double', then we use the following line inside the 
struct defition:

   alias value this;

What that line means is this: "Dear compiler, please automatically 
convert this type to whatever the type of the 'value' member is." In 
this case, "Allow using an object of Money wherever that object is used 
in place of a double."

So, with that addition, now the call inside main compiles and foo() gets 
called with 'Money(20, 50).value' (compiler injects an automatic call to 
value()).

Here is the complete program:

struct Money {
   long dollars;
   long cents;

   double value() const {
     return double(cents) / 100 + dollars;
   }

   alias value this;  // <-- ADDED
}

unittest {
   assert(Money(10, 50).value == 10.5);
}

void foo(double d) {
   // ...
}

void main() {
   foo(Money(20, 50));
}

'alias this' is sometimes used where a type needs to behave like some 
other type with some added functionality. For example, here is another 
example where a Month type should behave like an 'int' but it cannot 
have any value other than 1-12:

struct Month {
   int value;

   this(int value) {
     this.value = value;
   }

   invariant() {
     assert(value >= 1);
     assert(value <= 12);
   }

   alias value this;
}

unittest {
   import std.exception;

   assertThrown!Error(Month(0));
   assertThrown!Error(Month(13));

   void foo(int) {
   }

   // 'alias this' allows the following call to foo()
   assert(__traits(compiles, foo(Month(3))));
}

void main() {
}

Ali



More information about the Digitalmars-d-learn mailing list