digitalmars.D.learn - Instantiating a class with range template parameter
- Jon Degenhardt (36/36) Sep 08 2016 I've been generalizing output routines by passing an OutputRange
- Lodovico Giaretta (22/60) Sep 08 2016 I think that
- Jon Degenhardt (4/29) Sep 08 2016 Yes, the form you suggested works, thanks! And thanks for the
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"); }
Sep 08 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 }
Sep 08 2016
On Thursday, 8 September 2016 at 08:44:54 UTC, Lodovico Giaretta wrote:On Thursday, 8 September 2016 at 08:20:49 UTC, Jon Degenhardt wrote:Yes, the form you suggested works, thanks! And thanks for the class structuring suggestion, it has some nice properties.[snip]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 }
Sep 08 2016