Bug 14477 – Nullable does not work with structs with default constructor disabled
Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P1
Component
phobos
Product
D
Version
D2
Platform
All
OS
All
Creation time
2015-04-21T18:12:51Z
Last change time
2017-12-18T22:56:54Z
Keywords
pull
Assigned to
No Owner
Creator
Justin Whear
Comments
Comment #0 by justin — 2015-04-21T18:12:51Z
The following simple code does not compile:
--------------------------
import std.typecons;
struct Foo
{
int x;
@disable this();
this(int value) { x=value; }
}
void main()
{
Nullable!Foo foo;
}
--------------------------
test.d(14): Error: variable test.main.foo default construction is disabled for type Nullable!(Foo)
Of course, one of the major use-cases for Nullable is to provide a way to default-initialize such a struct to a "null" state.
Comment #1 by dlang.org — 2016-07-18T07:58:38Z
I see the pull-request from when this issue was filed was retracted, as this is evidently - in terms of implementation - a lot more subtle than it initially sounds.
Is it really still being worked on?
Comment #2 by justin — 2016-07-18T15:23:49Z
Afraid not.
Comment #3 by dlang.org — 2016-07-25T07:25:29Z
This is currently an issue for us, and it has been proposed we use Algebraic!Foo instead, which appears to work sufficiently, see below.
What aspects are against doing it this way?
The implementation of Algebraic "looks" a lot more heavyweight, but is it really, particularly in this very specific usage?
If we don't like the toString behaviour, or want to have .nullify, and prefer .isNull to .hasValue, we can always make Nullable a pretty minimal wrapper...
Thoughts?
-----
import std.variant;
import std.stdio;
import std.string;
struct Foo
{
int x;
@disable this();
this(int value) { x=value; }
}
void main()
{
Algebraic!Foo foo;
writeln("hasValue for default-initialized foo: %s".format(foo.hasValue));
writeln("Format default-initialized foo: %s".format(foo));
foo = Foo(5);
writeln("hasValue for set foo: %s".format(foo.hasValue));
writeln("Format set foo: %s".format(foo));
foo = Algebraic!Foo(); // Nullable's foo.nullify is cooler :/
writeln("hasValue for reset foo: %s".format(foo.hasValue));
writeln("Format reset foo: %s".format(foo));
}
--- output ---
hasValue for unset foo: false
Format unset foo: <Uninitialized VariantN>
hasValue for set foo: true
Format set foo: Foo(5)
hasValue for unset foo: false
Format unset foo: <Uninitialized VariantN>
Comment #4 by dlang.org — 2017-11-10T14:05:03Z
(In reply to MichaelZ from comment #3)
> This is currently an issue for us, and it has been proposed we use
> Algebraic!Foo instead, which appears to work sufficiently, see below.
>
> What aspects are against doing it this way?
More than a year of working around the issue in various ways, I looked at the Algebraic thing again: One disadvantage of Algebraic is that it doesn't have the same magical implicit .get behaviour as Nullable does :-|
Comment #5 by github-bugzilla — 2017-12-04T14:49:13Z