On Thursday, 4 October 2018 at 08:14:44 UTC, Simen Kjærås wrote:
On Thursday, 4 October 2018 at 07:31:21 UTC, Ritchie wrote:
Any reason why this works?
https://run.dlang.io/is/TALlyw
Yup.
Alright, so there's a few features in use here - which one are
you asking about?
1. Private constructor.
You can call the private constructor because the unit of
encapsulation in D is the module, not the type. So everything
is visible to everything else inside the same module.
2. @disable this()
This only disables default construction. Since you call a
different constructor, this doesn't affect the compilation.
3. @disable this(this)
This disables copy construction. In the example, no copying
occurs - the variable declaration leads to a move instead.
Simply put, copy construction requires that two copies exist
simultaneously, and in this case the potential second copy is
immediately destroyed, so no copy is necessary.
4. @disable void opAssign()
There's several reasons this doesn't affect compilation here.
First, the signature is wrong - you're disabling an opAssign
that takes no arguments. You're probably wanting to do @disable
void opAssign(X x);.
Now, even that isn't going to cause it to fail to compile in
this case though, since as in #3, what's happening on line 14
is move construction, not assignment. To force an assignment,
you need to have an object already:
X x = void;
x = X(5); // calls opAssign
So, now we've explained why it compiles. Currently, there's no
way to @disable or hook move construction. There's a DIP in the
works (DIP 1014) that aims to provide a hook into move
construction, but I don't see that it allows for @disabling it
altogether.
Hope this helps!
--
Simen
I apologize for not making it clear. I was talking about the
private constructor only. The @disable this() is there to prevent
struct literal syntax and the other disables really have no
reason to be there for the purpose of this question.
Oddly enough I asked this because I was working on something and
was able to call the private constructor from another module, but
then I created the run.dlang.io snippet to demo my problem.
I have this in one module: https://pastebin.com/J8r4fyK8
and this in another module:
void testUniquePtr() {
import bclib.memory.unique_ptr : Unique;
alias TestUnique = Unique!(int, TestMallocator);
{
auto unique = TestUnique(20);
assert(*unique == 20);
}
TestMallocator.check();
}
and it runs without complaints. (SmartPtrMembers doesnt have any
constructors in it)