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