Thread overview |
---|
January 28, 2019 Why isn't intended class constructor called? | ||||
---|---|---|---|---|
| ||||
I have defined a class that's meant to represent a data series, which has an index and a set of values. Sometimes the user wants to specify a particular index of custom type, other times they don't care and we want to default to an array of contiguous "int" starting from 0. I have attempted to create a class where the index type is a parameter, but defaults to int. I also tried to create two constructors: one for if the index values are not specified (in which the constructor makes the array of ints); and one where the user passes in a literal of values that match the specified type. However, it seems that only the first constructor is getting called, even though I am passing in two parameters instead of one. Why isn't the call matching the second constructor and behaving as intended? import std.stdio; class MyClass(T, U = int) { T[] values; U[] index; this(T[] values) { this.values = values; // Default index of contiguous ints for (int i; i < values.length; i++) { index ~= i; } } this(T[] values, U[] index) { this.values = values; this.index = index; } } void main() { auto myc1 = new MyClass!(int)([1,2,-3]); auto myc2 = new MyClass!(int, string)([1,2,-3], ["a", "b", "c"]); // Error: cannot append type int to type string[] } |
January 28, 2019 Re: Why isn't intended class constructor called? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Zak | On Monday, 28 January 2019 at 18:34:44 UTC, Zak wrote:
> I have defined a class that's meant to represent a data series, which has an index and a set of values. Sometimes the user wants to specify a particular index of custom type, other times they don't care and we want to default to an array of contiguous "int" starting from 0.
>
> I have attempted to create a class where the index type is a parameter, but defaults to int. I also tried to create two constructors: one for if the index values are not specified (in which the constructor makes the array of ints); and one where the user passes in a literal of values that match the specified type.
>
> However, it seems that only the first constructor is getting called, even though I am passing in two parameters instead of one. Why isn't the call matching the second constructor and behaving as intended?
>
>
> import std.stdio;
>
> class MyClass(T, U = int) {
>
> T[] values;
> U[] index;
>
> this(T[] values) {
> this.values = values;
> // Default index of contiguous ints
> for (int i; i < values.length; i++) {
> index ~= i;
> }
> }
>
> this(T[] values, U[] index) {
> this.values = values;
> this.index = index;
> }
> }
>
> void main() {
> auto myc1 = new MyClass!(int)([1,2,-3]);
>
> auto myc2 = new MyClass!(int, string)([1,2,-3], ["a", "b", "c"]); // Error: cannot append type int to type string[]
>
> }
As the error states:
you are trying to append an int to a string array in the single parameter constructor.
This would work:
´´´
import std.stdio;
class MyClass(T, U = int) {
T[] values;
U[] index;
this(T[] values) {
this.values = values;
// Default index of contiguous ints
static if(is(U == int))
{
for (int i; i < values.length; i++) {
index ~= i;
}
}
}
this(T[] values, U[] index) {
this.values = values;
this.index = index;
}
}
void main() {
auto myc1 = new MyClass!(int)([1,2,-3]);
auto myc2 = new MyClass!(int, string)([1,2,-3], ["a", "b", "c"]); // Error: cannot append type int to type string[]
}
´´´
If design matters, I would even to expand the static if above the constructor. So, the single parameter constructor would exist iff is(U == int)
´´´
static if(is(U == int))
{
this(T[] values) {
this.values = values;
// Default index of contiguous ints
for (int i; i < values.length; i++) {
index ~= i;
}
}
}
´´´
|
January 28, 2019 Re: Why isn't intended class constructor called? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Alex | On Monday, 28 January 2019 at 18:50:18 UTC, Alex wrote:
> On Monday, 28 January 2019 at 18:34:44 UTC, Zak wrote:
>> [...]
>
> As the error states:
> you are trying to append an int to a string array in the single parameter constructor.
>
> [...]
Thanks for the response, Alex! But it's not clear to me why the first constructor is called at all. Since I called with two parameters, shouldn't it invoke the second constructor?
|
January 28, 2019 Re: Why isn't intended class constructor called? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Zak | On Monday, 28 January 2019 at 19:15:04 UTC, Zak wrote:
> On Monday, 28 January 2019 at 18:50:18 UTC, Alex wrote:
>> On Monday, 28 January 2019 at 18:34:44 UTC, Zak wrote:
>>> [...]
>>
>> As the error states:
>> you are trying to append an int to a string array in the single parameter constructor.
>>
>> [...]
>
> Thanks for the response, Alex! But it's not clear to me why the first constructor is called at all. Since I called with two parameters, shouldn't it invoke the second constructor?
I think I just realized the answer: this section of code is not called, it just fails compilation since it's not known that runtime doesn't do something like:
auto myc = new MyClass!(int, string)([1,2,-3]);
which "would" invoke this code block with type string.
|
January 28, 2019 Re: Why isn't intended class constructor called? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Zak | On Monday, 28 January 2019 at 19:24:21 UTC, Zak wrote:
> On Monday, 28 January 2019 at 19:15:04 UTC, Zak wrote:
>> On Monday, 28 January 2019 at 18:50:18 UTC, Alex wrote:
>>> On Monday, 28 January 2019 at 18:34:44 UTC, Zak wrote:
>>>> [...]
>>>
>>> As the error states:
>>> you are trying to append an int to a string array in the single parameter constructor.
>>>
>>> [...]
>>
>> Thanks for the response, Alex! But it's not clear to me why the first constructor is called at all. Since I called with two parameters, shouldn't it invoke the second constructor?
>
> I think I just realized the answer: this section of code is not called, it just fails compilation since it's not known that runtime doesn't do something like:
>
> auto myc = new MyClass!(int, string)([1,2,-3]);
>
> which "would" invoke this code block with type string.
Yes. :)
|
Copyright © 1999-2021 by the D Language Foundation