Thread overview
initializing struct containing user defined type
Feb 18, 2022
kdevel
Feb 18, 2022
Ali Çehreli
Feb 18, 2022
kdevel
Feb 18, 2022
Ali Çehreli
Feb 18, 2022
Salih Dincer
Feb 18, 2022
Ali Çehreli
Feb 18, 2022
forkit
Feb 19, 2022
user1234@12.de
February 18, 2022
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?
February 18, 2022
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
February 18, 2022
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?

February 18, 2022
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

February 18, 2022

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

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?

February 18, 2022
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

February 18, 2022
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.


February 19, 2022

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.