www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Struct default constructors

reply Mehdi <randomemail gmail.com> writes:
I am trying to define a struct, and I want to add a default 
constructor. Additionally, I want to disable the default 
constructor to enforce the use of of this constructor. I did some 
research and found that it is possible to achieve this as follows 
in this link 
(https://forum.dlang.org/post/zmtssyredfqohwabvlnv forum.dlang.org):

```d
struct Test {
     disable this();
    // This makes it so `Test t;` won't work - you have to use a 
constructor of some sort

    this(int num) {
         // Construct it using the number
    }

    // `static opCall` makes `Test()` work when you spell it out
    static Test opCall() {
         Test t = Test(1);
         return t;
    }
}
```

However, when I try to compile this code, it doesn't work, and I 
get the following error message:

```
Error: struct `file.Test` `static opCall` is hidden by 
constructors and can never be called
dlang/source/file.d(72):        Please use a factory method 
instead, or replace all constructors with `static opCall`.
make: *** [Makefile:75: build/main] Error 1
/home/interface-d-cpp/src/interfacing-cpp/main/build
```

I'm wondering if there are any workarounds to make this work? It 
is not a significant issue as i can use factory method but it 
would more practical if this worked.
Aug 07 2023
next sibling parent IchorDev <zxinsworld gmail.com> writes:
On Monday, 7 August 2023 at 15:35:22 UTC, Mehdi wrote:
 ```d
 struct Test {
     disable this();
    // This makes it so `Test t;` won't work - you have to use a 
 constructor of some sort

    this(int num) {
         // Construct it using the number
    }

    // `static opCall` makes `Test()` work when you spell it out
    static Test opCall() {
         Test t = Test(1);
         return t;
    }
 }
 ```

 However, when I try to compile this code, it doesn't work, and 
 I get the following error message:

 ```
 Error: struct `file.Test` `static opCall` is hidden by 
 constructors and can never be called
 dlang/source/file.d(72):        Please use a factory method 
 instead, or replace all constructors with `static opCall`.
 make: *** [Makefile:75: build/main] Error 1
 /home/interface-d-cpp/src/interfacing-cpp/main/build
 ```
I don't think it's possible without removing ` disable this()`. Your options for workarounds depend on what you're trying to do. You could make every field private and use ` property` functions instead, make a factory function that returns a Voldemort type, etc.
Aug 09 2023
prev sibling next sibling parent FeepingCreature <feepingcreature gmail.com> writes:
On Monday, 7 August 2023 at 15:35:22 UTC, Mehdi wrote:
 I am trying to define a struct, and I want to add a default 
 constructor. Additionally, I want to disable the default 
 constructor to enforce the use of of this constructor. I did 
 some research and found that it is possible to achieve this as 
 follows in this link 
 (https://forum.dlang.org/post/zmtssyredfqohwabvlnv forum.dlang.org):

 ```d
 struct Test {
     disable this();
    // This makes it so `Test t;` won't work - you have to use a 
 constructor of some sort

    this(int num) {
         // Construct it using the number
    }

    // `static opCall` makes `Test()` work when you spell it out
    static Test opCall() {
         Test t = Test(1);
         return t;
    }
 }
 ```

 However, when I try to compile this code, it doesn't work, and 
 I get the following error message:

 ```
 Error: struct `file.Test` `static opCall` is hidden by 
 constructors and can never be called
 dlang/source/file.d(72):        Please use a factory method 
 instead, or replace all constructors with `static opCall`.
 make: *** [Makefile:75: build/main] Error 1
 /home/interface-d-cpp/src/interfacing-cpp/main/build
 ```

 I'm wondering if there are any workarounds to make this work? 
 It is not a significant issue as i can use factory method but 
 it would more practical if this worked.
This is specifically intended to not work. Struct parameterless construction is not supposed to run any code. What's more, `opCall` doesn't work with immutable members. This is the workaround we use in production: ```d Struct struct() => Struct(0); struct Struct { disable this(); this(int) { .... } } ``` It's one of the dumbest parts of the language.
Aug 10 2023
prev sibling parent ryuukk_ <ryuukk.dev gmail.com> writes:
On Monday, 7 August 2023 at 15:35:22 UTC, Mehdi wrote:
 I am trying to define a struct, and I want to add a default 
 constructor. Additionally, I want to disable the default 
 constructor to enforce the use of of this constructor. I did 
 some research and found that it is possible to achieve this as 
 follows in this link 
 (https://forum.dlang.org/post/zmtssyredfqohwabvlnv forum.dlang.org):

 ```d
 struct Test {
     disable this();
    // This makes it so `Test t;` won't work - you have to use a 
 constructor of some sort

    this(int num) {
         // Construct it using the number
    }

    // `static opCall` makes `Test()` work when you spell it out
    static Test opCall() {
         Test t = Test(1);
         return t;
    }
 }
 ```

 However, when I try to compile this code, it doesn't work, and 
 I get the following error message:

 ```
 Error: struct `file.Test` `static opCall` is hidden by 
 constructors and can never be called
 dlang/source/file.d(72):        Please use a factory method 
 instead, or replace all constructors with `static opCall`.
 make: *** [Makefile:75: build/main] Error 1
 /home/interface-d-cpp/src/interfacing-cpp/main/build
 ```

 I'm wondering if there are any workarounds to make this work? 
 It is not a significant issue as i can use factory method but 
 it would more practical if this worked.
You need set a param to ``opCall`` This works: ``` struct Test { int value; disable this(); this(int v) { } static Test opCall(int v) { Test t = Test(v); return t; } } void main() { Test t1; // NO Test t2 = {}; // NO Test t3 = {value: 42}; // NO Test tok = Test(42); // OK } ```
Aug 10 2023