Templates, constructors and default arguments
ketmar via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Wed Dec 24 18:28:35 PST 2014
On Thu, 25 Dec 2014 02:07:51 +0000
aldanor via Digitalmars-d-learn <digitalmars-d-learn at puremagic.com>
wrote:
> I'm wondering how to best implement the following pattern: the
> constructor of a class has some required and some optional
> arguments; and one of the (optional) arguments also controls if
> any additional arguments should be passed.
>
> A hypothetical/simplified example that I came up with: there's a
> Dataset class which requires size and rank to be set. Size is
> required; rank defaults to 1. There's also a "filebacked" boolean
> option that defaults to false; if specified, a bunch of
> additional arguments are available (like filename, mode, etc),
> some of which have default values. Ideally, I'd want to be able
> to construct it like this:
>
> // "new Dataset" could instead be a static factory method like
> "Dataset.create"
> // this is is purely hypothetical
> new Dataset; // fails, size required
> new Dataset(size); // filebacked=false, rank=1
> new Dataset(size, rank); // filebacked=false
> new Dataset(size, rank, "foo"); // fails, filename not applicable
> new Dataset!false(size); // rank=1
> new Dataset!true(size, rank); // fails, filename missing
> new Dataset!true(size, rank, "foo"); // mode = "w+"
> new Dataset!true(size, rank, "foo", "w+");
>
> If the "filebacked" argument only affects construction of the
> object and not its runtime behaviour, creating subclasses to
> solve this seems somewhat wrong. In fact, this argument doesn't
> even have to be a compile-time value but for the sake of being
> able to catch errors at compile time it probably should be.
>
> Templating the class like this
>
> class Dataset(filebacked = false)
>
> doesn't work since then "new Dataset(size)" is disallowed, in
> favor of "Dataset!()(size)".
>
> Adding a template factory function with variadic arg tuple like so
>
> Dataset create(bool filebacked = false, Args...)(uint size,
> uint rank = 1, Args args)
>
> doesn't work either because of the presence of default parameters
> ("default argument expected for args").
>
> I wonder if there's any way to hack around this?
you can create two or more constrained templates, for example? like
this:
import iv.writer;
void create(bool filebacked : false) (usize rank) {
writefln!"filebacked=false, rank=%s"(rank);
}
void create(bool filebacked : true) (usize rank, string fn, string mode="w+") {
writefln!"filebacked=true, rank=%s; fn=%s; mode=%s"(rank, fn, mode);
}
void create (usize rank=1) {
writef!"rank=%s : "(rank);
create!false(rank);
}
void main () {
create(); // "rank=1 : filebacked=false, rank=1"
create(42); // "rank=42 : filebacked=false, rank=42"
create!false(66); // "filebacked=false, rank=66"
create!true(99, "t"); // "filebacked=true, rank=99; fn=t; mode=w+"
}
happy hacking! ;-)
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 181 bytes
Desc: not available
URL: <http://lists.puremagic.com/pipermail/digitalmars-d-learn/attachments/20141225/41c451d0/attachment.sig>
More information about the Digitalmars-d-learn
mailing list