Re: Default struct constructors if a struct member is a union

2024-06-30 Thread Nick Treleaven via Digitalmars-d-learn

On Saturday, 29 June 2024 at 23:33:41 UTC, solidstate1991 wrote:

S foo0 = S(TypeEnum.Integer32, S(20));  //Ugly, but works
S foo1 = S(TypeEnum.Integer64, S(20L)); //Error: cannot


Did you mean `U(20)`? The 20 applies to the first field of the 
union, i32. `U(20L)` also works and (I think) it does the same 
because of VRP.


My question is can I initialize structs like these in one line 
without relying on a second line? My usecase scenario doesn't 
really allow constructors for the struct, since it's a binding 
to an external library via C API.


You can use a field initializer:
```d
enum TypeEnum { Integer32, Integer64 }

union U {
int i32;
long i64;
float f32;
double f64;
}

struct S {
TypeEnum type;
U data;
}

S foo0 = S(TypeEnum.Integer32, U(20)); // init i32
S foo1 = S(TypeEnum.Integer64, U(f32: 0.5F));

// struct initializer syntax
S foo2 = {TypeEnum.Integer32, {20}};
S foo3 = {TypeEnum.Integer64, {f32: 0.5F}}; // init f32

void main()
{
assert(foo0.data.i32 == 20);
assert(foo3.data.f32 == 0.5F);
}
```


Re: Default struct constructors if a struct member is a union

2024-06-30 Thread Basile B. via Digitalmars-d-learn

On Sunday, 30 June 2024 at 11:23:45 UTC, Nick Treleaven wrote:

On Saturday, 29 June 2024 at 23:33:41 UTC, solidstate1991 wrote:

S foo0 = S(TypeEnum.Integer32, S(20));  //Ugly, but works
S foo1 = S(TypeEnum.Integer64, S(20L)); //Error: cannot


Did you mean `U(20)`? The 20 applies to the first field of the 
union, i32. `U(20L)` also works and (I think) it does the same 
because of VRP.


My question is can I initialize structs like these in one line 
without relying on a second line? My usecase scenario doesn't 
really allow constructors for the struct, since it's a binding 
to an external library via C API.


You can use a field initializer:
```d
enum TypeEnum { Integer32, Integer64 }

union U {
int i32;
long i64;
float f32;
double f64;
}

struct S {
TypeEnum type;
U data;
}

S foo0 = S(TypeEnum.Integer32, U(20)); // init i32
S foo1 = S(TypeEnum.Integer64, U(f32: 0.5F));

// struct initializer syntax
S foo2 = {TypeEnum.Integer32, {20}};
S foo3 = {TypeEnum.Integer64, {f32: 0.5F}}; // init f32

void main()
{
assert(foo0.data.i32 == 20);
assert(foo3.data.f32 == 0.5F);
}
```


That's another solution, that being said, the real problem OP 
encountered is the classic one of "implict construction", which 
is not a D thing.