我正在对C ++和Delphi进行比较,我发现了一些棘手的问题。
这是非常简单的C ++代码:
C
在这种情况下,我们认为类D
是模板类(=泛型类),嵌套类T
也是模板类。如果double
为x
,则D
内的double
为template<typename T>
class C {
template<typename T>
class D {
T x;
}
}
。
我不能这样说:
C
这是一个错误,因为我已经在“内部”T
而另一个U
将是一个冲突。要修复错误,我应该使用其他名称,例如template<typename T>
class C {
template<typename U>
class D {
T x;
}
}
。
type
TClassC<T> = class
private
type
TClassD = class
private
x: T;
end;
end;
在Delphi中,我可以这样写:
T
如果integer
是x
,那么现在integer
是TClassD
,因为(据我所知,在线阅读)integer
是{{} 1}}。在德尔福,这也是合法的:
type
TClassC<T> = class
private
type
TClassD<T> = class // <-- note the <T> repeated!!
private
x: T;
end;
end;
现在呢?如果我能够在T
中再次声明TClassD
,这意味着如果没有<T>
,我会有一个非通用的TClassD
类。我是对的吗?
答案 0 :(得分:12)
考虑这个简单的程序:
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.
此程序编译,但会发出以下提示:
[dcc32提示]:H2509标识符&#39; T&#39;与容器类型
的类型参数冲突
赋值证明x
从外部泛型参数而不是内部参数中获取其类型。
我不得不说这令我感到惊讶,因为我期待相反的事情。我期待内部通用参数隐藏外部。事实上,据我所知,内部类型无法引用其泛型参数。
为了能够引用这两个通用参数,您需要为它们使用不同的名称。例如:
type
TClassC<T1> = class
private
type
TClassD<T2> = class
private
x: T2;
end;
end;
这就是类似的C ++模板代码强迫你做的事情。
在我看来,Delphi语言的设计缺点是你可以在这个答案的顶部编译代码。