Jump to page: 1 2
Thread overview
How do I initialize a templated constructor?
Aug 08, 2022
rempas
Aug 08, 2022
bauss
Aug 08, 2022
rempas
Aug 08, 2022
bauss
Aug 08, 2022
rempas
Aug 08, 2022
Dom Disc
Aug 08, 2022
Dom Disc
Aug 08, 2022
rempas
Aug 08, 2022
zjh
Aug 08, 2022
WebFreak001
Aug 08, 2022
Ali Çehreli
Aug 08, 2022
Ali Çehreli
Aug 08, 2022
rempas
August 08, 2022

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!

August 08, 2022

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);
August 08, 2022

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....

August 08, 2022

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.

August 08, 2022

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:

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

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

And then you can instantiate it with

auto val = TestArray!10(ubyte(60)); // if you want type to be ubyte
August 08, 2022

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!

August 08, 2022

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:

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....

August 08, 2022

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.

August 08, 2022

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:

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:

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.

« First   ‹ Prev
1 2