Re: How do I initialize a templated constructor?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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!