www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - initializing struct containing user defined type

reply kdevel <kdevel vogtner.de> writes:
Instead of using string I want to use A in the definition of B:

    struct A {
       string s;
       this (string s)
       {
          this.s = s;
       }
    }

    struct B {
       A a;
       A b;
    }

Alas I have some difficulty initializing a B in the accustomed 
manner (b3):

    void main ()
    {
       auto b0 = B (A ("A"), A ("B")); // as expected but I don't 
want
                                       // to change the client code

    //   B b1 = { {"A"}, {"B"} }; // works if A has no (explicit) 
ctor
                                  // but I don't want to write the 
braces

       B b2 = {"A", "B"}; // works but why?

    //   auto b3 = B ("A", "B"); // Error: cannot implicitly 
convert
    // expression `"A"` of type `string` to `A`
    }

Hasn't this been treated here before?
Feb 18 2022
parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 2/18/22 06:19, kdevel wrote:

     //   auto b3 = B ("A", "B"); // Error: cannot implicitly convert
     // expression `"A"` of type `string` to `A`
Yeah, D disallows some implicit conversions. Adding a constructor to B will make it work: this(string as, string bs) { this.a = A(as); this.b = A(bs); } } Ali
Feb 18 2022
parent reply kdevel <kdevel vogtner.de> writes:
On Friday, 18 February 2022 at 14:37:25 UTC, Ali Çehreli wrote:
 On 2/18/22 06:19, kdevel wrote:

     //   auto b3 = B ("A", "B"); // Error: cannot implicitly
convert
     // expression `"A"` of type `string` to `A`
Yeah, D disallows some implicit conversions. Adding a constructor to B will make it work: this(string as, string bs) { this.a = A(as); this.b = A(bs); } }
Okay. b0 needs an additional constructor with signature this (A, A). The initialization of b3 is now no longer working. dmd says: Error: struct `B` has constructors, cannot use `{ initializers }`, use `B( initializers )` instead What is the rationale behind that? I mean: If the compiler exactly sees what the program author intends to express why does it force the author to change the code?
Feb 18 2022
parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 2/18/22 07:01, kdevel wrote:

     Error: struct `B` has constructors, cannot use `{ initializers }`,
     use `B( initializers )` instead

 What is the rationale behind that? I mean: If the compiler exactly
 sees what the program author intends to express why does it force the
 author to change the code?
I don't know the answer to that. The {} initializers always seemed out of place to me. I assumed they had to be supported to copy+paste C code to D and it should mostly work. One benefit of the {} initializer is being able use named initializers: struct S { int a; int b; } void main() { S s = { b : 2, a : 1 }; } I still think it's out of place. :) I think that syntax will be obviated when D will have named arguments. Ali
Feb 18 2022
next sibling parent reply Salih Dincer <salihdb hotmail.com> writes:
On Friday, 18 February 2022 at 16:45:24 UTC, Ali Çehreli wrote:
 On 2/18/22 07:01, kdevel wrote:

     Error: struct `B` has constructors, cannot use `{
initializers }`,
     use `B( initializers )` instead

 What is the rationale behind that? I mean: If the compiler
exactly
 sees what the program author intends to express why does it
force the
 author to change the code?
I don't know the answer to that. The {} initializers always seemed out of place to me. I assumed they had to be supported to copy+paste C code to D and it should mostly work. One benefit of the {} initializer is being able use named initializers: struct S { int a; int b; } void main() { S s = { b : 2, a : 1 }; } I still think it's out of place. :) I think that syntax will be obviated when D will have named arguments. Ali
```d struct S { float a, b; disable this(this); } enum par : float { a = 1, b = 2 } S x = { b : par.b, a : par.a }; S y = S(par.a, par.b); auto s1 = x.a / x.b; auto s2 = y.a / y.b; s1.writeln(); s2.writeln(); writeln(s1 + s2); // x.writeln(y); // 2.087 "D Compiler v".writeln(__VERSION__/1000.0); ``` I'm using v2.087 but because of disable this line doesn't work: ```// x.writeln(y); // 2.087``` Why? Can you give an explanation for this?
Feb 18 2022
parent =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 2/18/22 12:16, Salih Dincer wrote:

    // x.writeln(y); // 2.087
    "D Compiler v".writeln(__VERSION__/1000.0);
 ```
 I'm using v2.087 but because of  disable this line doesn't work: ```//
 x.writeln(y); // 2.087```

 Why? Can you give an explanation for this?
This is not related to struct initialization. The issue can be reduced to the following: struct S { disable this(this); } void foo(S s) { } void main() { auto s = S(); foo(s); } Error: struct `deneme.S` is not copyable because it has a disabled postblit foo takes by-value but S disables copying. The same thing happens with your example inside a Phobos function: void write(S...)(S args) { // ... foreach (arg; args) // ... } foreach iterates the arguments by-value there. Same issue. Ali
Feb 18 2022
prev sibling parent reply forkit <forkit gmail.com> writes:
On Friday, 18 February 2022 at 16:45:24 UTC, Ali Çehreli wrote:
 ...
 I think that syntax will be obviated when D will have named 
 arguments.

 Ali
Huh? D doesn't have named arguments, already? That's an important component for safe(r) programming. Do you know if there is a DIP for this, and if so, it's current status.
Feb 18 2022
parent user1234 12.de <b2.temp gmx.com> writes:
On Friday, 18 February 2022 at 23:46:51 UTC, forkit wrote:
 On Friday, 18 February 2022 at 16:45:24 UTC, Ali Çehreli wrote:
 ...
 I think that syntax will be obviated when D will have named 
 arguments.

 Ali
Huh? D doesn't have named arguments, already? That's an important component for safe(r) programming. Do you know if there is a DIP for this, and if so, it's current status.
The DIP is [accepted] but not implemented. [accepted]: https://github.com/dlang/DIPs/blob/master/DIPs/accepted/DIP1030.md
Feb 18 2022