Thread overview
Private struct constructor
Oct 04, 2018
Ritchie
Oct 04, 2018
Andrea Fontana
Oct 04, 2018
Ritchie
Oct 04, 2018
John Chapman
Oct 04, 2018
Simen Kjærås
Oct 04, 2018
Ritchie
Oct 04, 2018
Simen Kjærås
Oct 04, 2018
Ritchie
October 04, 2018
Any reason why this works?

https://run.dlang.io/is/TALlyw
October 04, 2018
On Thursday, 4 October 2018 at 07:31:21 UTC, Ritchie wrote:
> Any reason why this works?
>
> https://run.dlang.io/is/TALlyw

Why not?
October 04, 2018
On Thursday, 4 October 2018 at 07:55:48 UTC, Andrea Fontana wrote:
> On Thursday, 4 October 2018 at 07:31:21 UTC, Ritchie wrote:
>> Any reason why this works?
>>
>> https://run.dlang.io/is/TALlyw
>
> Why not?

The constructor is private.
October 04, 2018
On Thursday, 4 October 2018 at 07:31:21 UTC, Ritchie wrote:
> Any reason why this works?
>
> https://run.dlang.io/is/TALlyw

"private" applies to the module, not the type. https://dlang.org/spec/attribute.html#visibility_attributes
October 04, 2018
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
October 04, 2018
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)
October 04, 2018
On Thursday, 4 October 2018 at 08:52:50 UTC, Ritchie wrote:
> 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.

Right. Reduced your example to this:

module bar;
struct S() {
    private this()(int n) {}
}

module foo;
unittest {
    import bar;
    auto a = S!()(3);
}

This is apparently a known issue:

https://issues.dlang.org/show_bug.cgi?id=18979

which is basically just a special case of this issue:

https://issues.dlang.org/show_bug.cgi?id=2775

--
  Simen
October 04, 2018
On Thursday, 4 October 2018 at 09:21:39 UTC, Simen Kjærås wrote:
> This is apparently a known issue:
>
> https://issues.dlang.org/show_bug.cgi?id=18979
>
> which is basically just a special case of this issue:
>
> https://issues.dlang.org/show_bug.cgi?id=2775
>
> --
>   Simen

I see. Looks like the chances of it being fixed anytime soon are slim. Thanks for the info.