Re: How do I initialize a templated constructor?

2022-08-08 Thread rempas via Digitalmars-d-learn
Thank you all for the info! I'll try to find another way to do it 
as it is not possible

to match the exact behavior I want! Have a great day everyone!



Re: How do I initialize a templated constructor?

2022-08-08 Thread Ali Çehreli via Digitalmars-d-learn

Here is another one that uses nested templates:

import std.stdio;

template TestArray(ulong element_n) {
  struct TestArrayImpl(Type) {
int[element_n] elements;

this(ulong number) {
  pragma(msg, "The type is: ", Type);
  writeln("Constructing with ", number);
}
  }

  auto makeFor(string s)(ulong number) {
return TestArrayImpl!(mixin(s))(number);
  }
}

void main() {
  auto ta = TestArray!10.makeFor!"int"(60);
}

Ali



Re: How do I initialize a templated constructor?

2022-08-08 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/8/22 9:36 AM, Steven Schveighoffer wrote:

On 8/8/22 1:38 AM, rempas wrote:

In the following struct (as an example, not real code):

```
struct TestArray(ulong element_n) {
   int[element_n] elements;

   this(string type)(ulong number) {
 pragma(msg, "The type is: " ~ typeof(type).stringof);
   }
}
```

I want to create it and be able to successfully initialize the 
template parameters
of the constructor but until now, I wasn't able to find a way to 
successfully do

that. Is there a way you guys know?  I have tried the following:

```
void main() {
   // Doesn't work
   auto val = TestArray!(10, "int")(60);

   // Doesn't work either
   auto val = TestArray!(10).TestArray!("int")(60);

   // Neither this works
   auto val = TestArray!(10).this!("int")(60);
}
```

As with every question I make, the solution must be "betterC" 
compatible so I can use it.

Thanks a lot!


You cannot explicitly specify template parameters for constructors.

The only true solution is to use a factory function:

```d
TestArray!T testarray(string s, T)(T val) {
    ... // code that depends on s here
    return TestArray!T(...) // call ctor here.
}
```


Just thought of another possibility:

```d
struct StringAnnotated(string s, T)
{
   T val;
}

StringAnnotated!(s, T) annotate(string s, T)(T val)
{
   return StringAnnotated!(s, T)(val);
}

struct TestArray(ulong element_n)
{
   ...
   this(T)(T val) if (isInstanceOf!(StringAnnotated, T))
   {
  ...
   }
}

// use like
TestArray!10(60.annotate!"int");
```

-Steve


Re: How do I initialize a templated constructor?

2022-08-08 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/8/22 1:38 AM, rempas wrote:

In the following struct (as an example, not real code):

```
struct TestArray(ulong element_n) {
   int[element_n] elements;

   this(string type)(ulong number) {
     pragma(msg, "The type is: " ~ typeof(type).stringof);
   }
}
```

I want to create it and be able to successfully initialize the template 
parameters
of the constructor but until now, I wasn't able to find a way to 
successfully do

that. Is there a way you guys know?  I have tried the following:

```
void main() {
   // Doesn't work
   auto val = TestArray!(10, "int")(60);

   // Doesn't work either
   auto val = TestArray!(10).TestArray!("int")(60);

   // Neither this works
   auto val = TestArray!(10).this!("int")(60);
}
```

As with every question I make, the solution must be "betterC" compatible 
so I can use it.

Thanks a lot!


You cannot explicitly specify template parameters for constructors.

The only true solution is to use a factory function:

```d
TestArray!T testarray(string s, T)(T val) {
   ... // code that depends on s here
   return TestArray!T(...) // call ctor here.
}
```

-Steve


Re: How do I initialize a templated constructor?

2022-08-08 Thread Ali Çehreli via Digitalmars-d-learn

On 8/7/22 22:38, rempas wrote:

> I want to create it and be able to successfully initialize the template
> parameters
> of the constructor but until now, I wasn't able to find a way to
> successfully do
> that.

The following method uses a convenience function but it's not really needed:

import std.stdio;

struct TestArray(ulong element_n, string type) {
  int[element_n] elements;
  mixin(type) member;
  pragma(msg, "The type is: ", typeof(member));

  this(ulong number) {
writeln("Constructing with ", number);
  }
}

auto makeTestArray(ulong element_n, string type)(ulong number) {
  return TestArray!(element_n, type)(number);
}

void main() {
  auto ta = makeTestArray!(10, "int")(60);
}

Ali



Re: How do I initialize a templated constructor?

2022-08-08 Thread WebFreak001 via Digitalmars-d-learn

On Monday, 8 August 2022 at 05:38:31 UTC, rempas wrote:

In the following struct (as an example, not real code):

```
struct TestArray(ulong element_n) {
  int[element_n] elements;

  this(string type)(ulong number) {
pragma(msg, "The type is: " ~ typeof(type).stringof);
  }
}
```

I want to create it and be able to successfully initialize the 
template parameters
of the constructor but until now, I wasn't able to find a way 
to successfully do

that. Is there a way you guys know?  I have tried the following:

```
void main() {
  // Doesn't work
  auto val = TestArray!(10, "int")(60);

  // Doesn't work either
  auto val = TestArray!(10).TestArray!("int")(60);

  // Neither this works
  auto val = TestArray!(10).this!("int")(60);
}
```

As with every question I make, the solution must be "betterC" 
compatible so I can use it.

Thanks a lot!


I would move the constructor out of the struct into a helper 
function, either global or as a static member:


```d
TestArray!n testArray(ulong n, string type)(ulong number) {
TestArray!n ret;
pragma(msg, "The type is: " ~ typeof(type).stringof);

ret.something = something; // do your constructor logic here

return ret;
}
```

which you can then use:

```d
auto t = testArray!(10, "int")(60);
```

As the template parameter being part of the constructor would 
only change the constructor (and can't change anything like types 
outside the ctor) it doesn't have any limitations and if you 
define it in the same module as the struct you can also access 
the private members.


Re: How do I initialize a templated constructor?

2022-08-08 Thread zjh via Digitalmars-d-learn

On Monday, 8 August 2022 at 12:26:50 UTC, rempas wrote:

On Monday, 8 August 2022 at 11:03:21 UTC, Dom Disc wrote:


You should first describe what you want to do clearly.


Re: How do I initialize a templated constructor?

2022-08-08 Thread rempas via Digitalmars-d-learn

On Monday, 8 August 2022 at 11:03:21 UTC, Dom Disc wrote:


But if you only want to know the type of the parameter, you can 
do this:


```D
struct TestArray(ulong element_n) {
  int[element_n] elements;

  this(type)(type number)
  {
pragma(msg, "The type is: " ~ type.stringof);
  }
}
```


Unfortunately this will not do as well


Re: How do I initialize a templated constructor?

2022-08-08 Thread rempas via Digitalmars-d-learn

On Monday, 8 August 2022 at 08:27:49 UTC, bauss wrote:


Yeah I think the only template argument you can have for 
constructors are `this` which will refer to things like the 
class that inherited the current class etc. not sure what else, 
but you can't really pass anything to it yourself unfortunately.



It's fine, thanks for trying in any case!

But I think if you end up with something where you need 
different constructors with different type arguments then 
you're probably designing your program in a "wrong" way to 
begin with.



Oh, trust me! I didn't designed my program wrong in my case.
At least not the way I see it!


Re: How do I initialize a templated constructor?

2022-08-08 Thread Dom Disc via Digitalmars-d-learn

And then you can instantiate it with

```D
auto val = TestArray!10(ubyte(60)); // if you want type to be 
ubyte

```




Re: How do I initialize a templated constructor?

2022-08-08 Thread Dom Disc via Digitalmars-d-learn

On Monday, 8 August 2022 at 06:58:42 UTC, bauss wrote:

On Monday, 8 August 2022 at 05:38:31 UTC, rempas wrote:

In the following struct (as an example, not real code):

```
struct TestArray(ulong element_n) {
  int[element_n] elements;

  this(string type)(ulong number) {
pragma(msg, "The type is: " ~ typeof(type).stringof);
  }
}
```


You cannot do this.


But if you only want to know the type of the parameter, you can 
do this:


```D
struct TestArray(ulong element_n) {
  int[element_n] elements;

  this(type)(type number)
  {
pragma(msg, "The type is: " ~ type.stringof);
  }
}
```



Re: How do I initialize a templated constructor?

2022-08-08 Thread bauss via Digitalmars-d-learn

On Monday, 8 August 2022 at 07:37:16 UTC, rempas wrote:


Thank you for all the great info! Unfortunately, while there is 
no problem in this example, this will
not do for my real code as I need to have the argument in the 
constructor. Alternative, I have to

change the design of the program completely


Yeah I think the only template argument you can have for 
constructors are `this` which will refer to things like the class 
that inherited the current class etc. not sure what else, but you 
can't really pass anything to it yourself unfortunately.


But I think if you end up with something where you need different 
constructors with different type arguments then you're probably 
designing your program in a "wrong" way to begin with.


Re: How do I initialize a templated constructor?

2022-08-08 Thread rempas via Digitalmars-d-learn

On Monday, 8 August 2022 at 06:58:42 UTC, bauss wrote:


```
this(string type)(ulong number) {
```

You cannot do this.

Instead your type should look like this:

First let's change it up a little bit.

```
struct TestArray(ulong element_n, string type) {
  int[element_n] elements;

  this(ulong number) {
pragma(msg, "The type is: " ~ typeof(type).stringof);
  }
}
```

Now the above will still not work because you do `typeof(type)` 
which will always yield string because type is as string and 
also the typeof() is not needed in this case and will actually 
yield an error.


If it must be a string then you can do it like this:

```
struct TestArray(ulong element_n, string type) {
  int[element_n] elements;

  this(ulong number) {
mixin("alias T = " ~ type ~ ";");
pragma(msg, "The type is: " ~ T.stringof);
  }
}
```

However the ideal implementation is probably this:

```
struct TestArray(ulong element_n, T) {
  int[element_n] elements;

  this(ulong number) {
pragma(msg, "The type is: " ~ T.stringof);
  }
}
```

To instantiate it you simply do:

```
TestArray!(10, "int") val = TestArray!(10, "int")(100);
```

Or

```
TestArray!(10, int) val = TestArray!(10, int)(100);
```

I will recommend an alias to make it easier:

```
alias IntTestArray = TestArray!(10, int);

...

IntTestArray val = IntTestArray(100);
```


Thank you for all the great info! Unfortunately, while there is 
no problem in this example, this will
not do for my real code as I need to have the argument in the 
constructor. Alternative, I have to

change the design of the program completely


Re: How do I initialize a templated constructor?

2022-08-08 Thread bauss via Digitalmars-d-learn

On Monday, 8 August 2022 at 05:38:31 UTC, rempas wrote:

In the following struct (as an example, not real code):

```
struct TestArray(ulong element_n) {
  int[element_n] elements;

  this(string type)(ulong number) {
pragma(msg, "The type is: " ~ typeof(type).stringof);
  }
}
```

I want to create it and be able to successfully initialize the 
template parameters
of the constructor but until now, I wasn't able to find a way 
to successfully do

that. Is there a way you guys know?  I have tried the following:

```
void main() {
  // Doesn't work
  auto val = TestArray!(10, "int")(60);

  // Doesn't work either
  auto val = TestArray!(10).TestArray!("int")(60);

  // Neither this works
  auto val = TestArray!(10).this!("int")(60);
}
```

As with every question I make, the solution must be "betterC" 
compatible so I can use it.

Thanks a lot!


```
this(string type)(ulong number) {
```

You cannot do this.

Instead your type should look like this:

First let's change it up a little bit.

```
struct TestArray(ulong element_n, string type) {
  int[element_n] elements;

  this(ulong number) {
pragma(msg, "The type is: " ~ typeof(type).stringof);
  }
}
```

Now the above will still not work because you do `typeof(type)` 
which will always yield string because type is as string and also 
the typeof() is not needed in this case and will actually yield 
an error.


If it must be a string then you can do it like this:

```
struct TestArray(ulong element_n, string type) {
  int[element_n] elements;

  this(ulong number) {
mixin("alias T = " ~ type ~ ";");
pragma(msg, "The type is: " ~ T.stringof);
  }
}
```

However the ideal implementation is probably this:

```
struct TestArray(ulong element_n, T) {
  int[element_n] elements;

  this(ulong number) {
pragma(msg, "The type is: " ~ T.stringof);
  }
}
```

To instantiate it you simply do:

```
TestArray!(10, "int") val = TestArray!(10, "int")(100);
```

Or

```
TestArray!(10, int) val = TestArray!(10, int)(100);
```

I will recommend an alias to make it easier:

```
alias IntTestArray = TestArray!(10, int);

...

IntTestArray val = IntTestArray(100);
```


How do I initialize a templated constructor?

2022-08-07 Thread rempas via Digitalmars-d-learn

In the following struct (as an example, not real code):

```
struct TestArray(ulong element_n) {
  int[element_n] elements;

  this(string type)(ulong number) {
pragma(msg, "The type is: " ~ typeof(type).stringof);
  }
}
```

I want to create it and be able to successfully initialize the 
template parameters
of the constructor but until now, I wasn't able to find a way to 
successfully do

that. Is there a way you guys know?  I have tried the following:

```
void main() {
  // Doesn't work
  auto val = TestArray!(10, "int")(60);

  // Doesn't work either
  auto val = TestArray!(10).TestArray!("int")(60);

  // Neither this works
  auto val = TestArray!(10).this!("int")(60);
}
```

As with every question I make, the solution must be "betterC" 
compatible so I can use it.

Thanks a lot!