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








Jon Degenhardt <jond noreply.com>