Re: How to construct a struct that does not explicitly define a constructor

2025-03-01 Thread Paul Backus via Digitalmars-d-learn

On Saturday, 1 March 2025 at 03:13:55 UTC, user1234 wrote:
because the tuple-expression `(0,0.1)` is explicitly 
convertible to `Test`, based on the concept of "structural 
typing".


Even if D has tuples, I highly doubt that it will have this kind 
of implicit conversion from tuples to structs. D is generally 
very conservative about what implicit conversions it allows, 
especially conversions to and from user-defined types (like 
structs and classes).


Re: How to construct a struct that does not explicitly define a constructor

2025-02-28 Thread user1234 via Digitalmars-d-learn

On Saturday, 1 March 2025 at 02:19:55 UTC, Meta wrote:


Thanks, I forgot about that syntax. Another question I have is 
if there's a way to do this inline:


```d
struct Test
{
int n;
float f;

static Test opCall(int n, float f)
{
//return {n, f};Error
//return Test {n, f};   Error
//return {n: n, f: f};  Error
//return Test {n: n, f: f}; Error
}
}

void main()
{
auto test = Test(1, 2.0);
assert(test.n == 1);
assert(test.f == 2.0);
}
```


As you've been said, that does not work ATM but that is something 
that I expect to work from day one when D will have tuples


```d
struct Test
{
int n;
double f;
static Test opCall(int n, float f)
{
return (0,0.1);
}
}
```

because the tuple-expression `(0,0.1)` is explicitly convertible 
to `Test`, based on the concept of "structural typing".


Re: How to construct a struct that does not explicitly define a constructor

2025-02-28 Thread Paul Backus via Digitalmars-d-learn

On Saturday, 1 March 2025 at 02:19:55 UTC, Meta wrote:

On Saturday, 1 March 2025 at 00:47:20 UTC, Paul Backus wrote:

What you can do is use curly-brace initialization syntax:



Thanks, I forgot about that syntax. Another question I have is 
if there's a way to do this inline:


No, there's no way to do it inline.

Really, the ideal solution here would be to get rid of your 
`static opCall` overload (for example, by turning it into a 
regular `static` method instead).


Re: How to construct a struct that does not explicitly define a constructor

2025-02-28 Thread Meta via Digitalmars-d-learn

On Saturday, 1 March 2025 at 00:47:20 UTC, Paul Backus wrote:

What you can do is use curly-brace initialization syntax:

```d
struct Test
{
int n;
float f;

static Test opCall(int n, float f)
{
Test result = { n, f };
return result;
}
}

void main()
{
auto test = Test(1, 2.0);
assert(test.n == 1);
assert(test.f == 2.0);
}
```


Thanks, I forgot about that syntax. Another question I have is if 
there's a way to do this inline:


```d
struct Test
{
int n;
float f;

static Test opCall(int n, float f)
{
//return {n, f};Error
//return Test {n, f};   Error
//return {n: n, f: f};  Error
//return Test {n: n, f: f}; Error
}
}

void main()
{
auto test = Test(1, 2.0);
assert(test.n == 1);
assert(test.f == 2.0);
}
```


Re: How to construct a struct that does not explicitly define a constructor

2025-02-28 Thread Paul Backus via Digitalmars-d-learn

On Friday, 28 February 2025 at 23:31:23 UTC, Meta wrote:

```d
struct Test
{
int n;
float f;

static Test opCall(int n, float f)
{
return Test(n, f);
}
}

void main()
{
Test(1, 2.0);
}
```

This code causes an infinite loop because the `Test(n, f)` 
inside the static `opCall` is interpreted as a recursive call 
to that same `opCall` function - not a call to the struct's 
constructor (or however this is interpreted by the compiler 
when there is no explicit struct/union constructor defined).


I tried doing `return Test.__ctor(n, f)` but it says that 
symbol doesn't exist. Is there any way to explicitly call the 
struct's constructor so it doesn't cause an infinitely 
recursive call to `opCall`?


You can't call the constructor because there isn't one.

What you can do is use curly-brace initialization syntax:

```d
struct Test
{
int n;
float f;

static Test opCall(int n, float f)
{
Test result = { n, f };
return result;
}
}

void main()
{
auto test = Test(1, 2.0);
assert(test.n == 1);
assert(test.f == 2.0);
}
```