Instantiating a class with range template parameter

Lodovico Giaretta via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Thu Sep 8 01:44:54 PDT 2016


On Thursday, 8 September 2016 at 08:20:49 UTC, Jon Degenhardt 
wrote:
> I've been generalizing output routines by passing an 
> OutputRange as an argument. This gets interesting when the 
> output routine is an virtual function. Virtual functions cannot 
> be templates, so instead the template parameters need to be 
> part of class definition and specified when instantiating the 
> class.
>
> An example is below. It works fine. One thing I can't figure 
> out: how to provide the range parameter without first declaring 
> a variable of the appropriate type. What works is something 
> like:
>
>     auto writer = stdout.lockingTextWriter;
>     auto x = new Derived!(typeof(writer));
>
> Other forms I've tried fail to compile. For example, this fails:
>
>     auto x = new Derived!(typeof(stdout.lockingTextWriter));
>
> I'm curious if this can be done without declaring the variable 
> first. Anyone happen to know?
>
> --Jon
>
> Full example:
>
> import std.stdio;
> import std.range;
>
> class Base(OutputRange)
> {
>     abstract void writeString(OutputRange r, string s);
> }
>
> class Derived(OutputRange) : Base!OutputRange
> {
>     override void writeString(OutputRange r, string s)
>     {
>         put(r, s);
>         put(r, '\n');
>     }
> }
>
> void main()
> {
>     auto writer = stdout.lockingTextWriter;
>     auto x = new Derived!(typeof(writer));
>     x.writeString(writer, "Hello World");
> }

I think that

auto x = new Derived!(typeof(stdout.lockingTextWriter()))(); // 
note the parenthesis

should work.



But usually, you save the writer inside the object and make a 
free function called `derived` (same as the class, but with 
lowercase first). You define it this way:

auto derived(OutputRange)(auto ref OutputRange writer)
{
     auto result = new Derived!OutputRange();
     result.writer = writer; // save the writer in a field of the 
object
     return result;
}

void main()
{
     auto x = derived(stdout.lockingTextWriter);
     x.writeString("Hello world");   // the writer is saved in the 
object, no need to pass it
}


More information about the Digitalmars-d-learn mailing list