Allowing arbitrary types for a function's argument and return type

Adam D. Ruppe via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Thu Oct 22 06:58:54 PDT 2015


On Thursday, 22 October 2015 at 13:53:33 UTC, pineapple wrote:
> import std.concurrency;
> Generator!int sequence(int i){
>     return new Generator!int({
>         yield(i);
>         while(i > 1){
>             yield(i = (i % 2) ? (i * 3 + 1) : (i >> 1));
>         }
>     });
> }
>
> Which can be used like so:
>
> import std.stdio;
> void main(){
>     foreach(i; sequence(11)){
>         writeln(i);
>     }
> }
>
> And now I'd like to make one more improvement, but this I 
> haven't been able to figure out. What if I wanted the argument 
> and output types to be longs instead of ints?

D's templates are easy (you actually used one in there, the 
Generator is one!)

Try this:

import std.concurrency;
Generator!T sequence(T)(T i){
     return new Generator!T({
         yield(i);
         while(i > 1){
             yield(i = (i % 2) ? (i * 3 + 1) : (i >> 1));
         }
     });
}


The first set of args, `(T)`, are the template arguments. You can 
then use hat anywhere in teh function as a type placeholder.


Now, when you call it, it can automatically deduce the types:

      foreach(i; sequence(11)){ // still works, uses int
      foreach(i; sequence(11L)){ // also works, uses long now

Or you can tell your own args explicitly:

      foreach(i; sequence!long(11)){ // uses long



The pattern is name!(template, args, ...)(regular, args...)

The ! introduces template arguments. If there is just one simple 
argument - one consisting of a single word - you can leaves the 
parenthesis out.


More information about the Digitalmars-d-learn mailing list