Explicit default constructor for structs
monarch_dodra
monarchdodra at gmail.com
Thu Apr 10 04:13:43 PDT 2014
On Wednesday, 9 April 2014 at 18:41:57 UTC, Walter Bright wrote:
> On 4/9/2014 7:59 AM, Benjamin Thaut wrote:
>> What do you think? C&C welcome.
>
> Or you could use a factory function:
>
> struct Foo {
> static Foo factory() { ... }
> ...
> }
>
> auto foo = Foo.factory();
Yeah. For sure.
Or a named function: auto foo = foo();
Or a make template: auto foo = make!Foo();
Or a dummy argument: auto foo = Foo(Foo.dummy);
Or ditto with a global dummy: auto foo = Foo(dummyArg);
Or use a static opCall: auto foo = Foo();
Or use an initialize function: Foo foo; foo.initialize();
I mean: Why complain when there are at least 10 *different*
solutions at our disposal? Who doesn't love re-inventing the same
functionality over and over and over again? But more importantly,
who doesn't just *love* reading the documentation that explains
*which* approach the damn type chose for run-time initialization.
Yummy!
Also, any kind of "Factory" solution has a postblit overhead if
you try to emplace it. Or would require a temporary with some
complex "uninitializedMove". No postblit, but still overhead.
--------
Being serious again, if the language isn't going to do something
to address the issue, we *should* have a uniform library solution.
I think the "make" template could be a good approach. It could be
a universal construction scheme, with "opt-in" no-arg
construction:
static struct NoArg {}
enum noArgToken;
template make(T)
{
//And some switches to handle non-struct types too.
T make(Args...)(auto ref Args args)
{
static if (Args.length)
return T(args);
else
{
static if (is(typeof(T(noArgToken))));
return T(noArgToken);
else
return T();
}
}
}
struct S1
{
int* p;
@disable this();
this(NoArg) //Opt-in no-arg constructor
{p = new int;}
}
struct S2
{
int i;
}
void main()
{
S1 s11; //FAils to compile (disabled this());
auto s12 = S1.init; //Explicit request for static default
initialization;
auto s13 = make!S1(); //run-time construction request.
auto s2 = make!S2(); //run-time construction request. Does
nothing particular.
}
This has the advantage (IMO) of being explicit and universal.
Also, it's an actual construction scheme, so
`emplace(noArgToken)` would call an actual constructor.
Furthermore, it could also allow a universal construction scheme
for items, regardless of struct/class/integral etc...
More information about the Digitalmars-d
mailing list