I was doing a comparison between C++ and Delphi and I found something tricky to me.
This is very easy C++ code:
template<typename T>
class C {
class D {
T x;
}
}
In this scenario, we have that the class C
is a template class ( = generic class) and the nested class D
is also a template class. If T
is a double
, the x
inside D
is double
.
I cannot say this:
template<typename T>
class C {
template<typename T>
class D {
T x;
}
}
That is an error since I am already "inside" C
and another T
would be a conflict. To fix the error, I should use a different name, like U
.
template<typename T>
class C {
template<typename U>
class D {
T x;
}
}
In Delphi, I could write this:
type
TClassC<T> = class
private
type
TClassD = class
private
x: T;
end;
end;
If T
is an integer
, now x
is an integer
since (from what I've understood reading online) the TClassD
is integer
. In Delphi this is also legal:
type
TClassC<T> = class
private
type
TClassD<T> = class // <-- note the <T> repeated!!
private
x: T;
end;
end;
What about now? If I am able to declare T
again in TClassD
, this means that without the <T>
I'd have a non-generic TClassD
class. Am I correct?
Consider this simple program:
type
TClassC<T> = class
private
type
TClassD<T> = class
private
x: T;
end;
end;
var
obj: TClassC<Integer>.TClassD<string>;
begin
obj := TClassC<Integer>.TClassD<string>.Create;
obj.x := 42;
end.
This program compiles, but emits the following hint:
[dcc32 Hint]: H2509 Identifier 'T' conflicts with type parameters of container type
The assignment proves that x
takes its type from the outer generic parameter rather than the inner.
I have to say that this surprised me because I was expecting the opposite. I was expecting that the inner generic parameter would hide the outer. In fact, so far as I can tell, there is no way for the inner type to refer to its generic parameter.
In order to be able to refer to both generic parameters you would need to use different names for them. For instance:
type
TClassC<T1> = class
private
type
TClassD<T2> = class
private
x: T2;
end;
end;
This is what the analagous C++ template code forces you to do.
In my view, it is a design weakness of the Delphi language that you are permitted to compile the code at the top of this answer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With