Delphi泛型嵌套类 我正在做C++与Delphi的比较,我发现了一些棘手的问题。 这是非常容易的C++代码: 模板 C类{ D类{ tx; } }

Delphi泛型嵌套类 我正在做C++与Delphi的比较,我发现了一些棘手的问题。 这是非常容易的C++代码: 模板 C类{ D类{ tx; } },delphi,generics,Delphi,Generics,在这个场景中,类C是一个模板类(=泛型类),嵌套类D也是一个模板类。如果T是double,则D内的x是double 我不能这样说: 模板 C类{ 模板 D类{ tx; } } 这是一个错误,因为我已经“在”C内,而另一个T将是冲突。要修复错误,我应该使用不同的名称,如U 模板 C类{ 模板 D类{ tx; } } 在Delphi中,我可以这样写: 类型 TClassC=class 私有的 类型 TClassD=class 私有的 x:T; 结束; 结束; 如果T是一个整数,那么现在x是一个

在这个场景中,类
C
是一个模板类(=泛型类),嵌套类
D
也是一个模板类。如果
T
double
,则
D
内的
x
double

我不能这样说:

模板
C类{
模板
D类{
tx;
}
}
这是一个错误,因为我已经“在”
C
内,而另一个
T
将是冲突。要修复错误,我应该使用不同的名称,如
U

模板
C类{
模板
D类{
tx;
}
}
在Delphi中,我可以这样写:

类型
TClassC=class
私有的
类型
TClassD=class
私有的
x:T;
结束;
结束;
如果
T
是一个
整数
,那么现在
x
是一个
整数
,因为(从我在线阅读的理解来看,
TClassD
整数
。在德尔福,这也是合法的:

类型
TClassC=class
私有的
类型

TClassD=class/考虑一下这个简单的程序:

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.

这就是恶意的C++模板代码强迫你做的事情。


在我看来,允许您编译此答案顶部的代码是Delphi语言的一个设计弱点。

应该很容易检查这一点,但我希望如果此代码编译,内部T会隐藏外部T。所以,这就像您对内部类型参数使用了不同的名称一样。比如 TCaseC,然后是代码> tCordD 。换句话说,我的预期是,Delphi代码的行为完全与C++版本没有冲突的参数名一致。但是C++语言保护你不受名字冲突。在你的第一个C++例子中,<代码> d>代码>本身不是模板类,从 C<代码>的模板只是在范围内,所以代码> d>代码>可以使用它。在第二个C++示例中,有两个模板参数,即命名为<> > t>代码>,实际上是命名冲突,因为C++不喜欢在同一范围内重复标识符。Delphi泛型与C++模板(即使它们使用类似的语法)也不一样,Delphi在这个特定的例子中比C++更灵活一些。谢谢戴维和ReMy。另外@RemyLebeau您的“稍微灵活一点”意味着它允许使用相同的参数声明嵌套类型?在本例中,顺便提一下,我希望两个类(如我上一个示例中)具有相同的类型@拉斐尔:不是使用相同的参数(那将是无用的),只是使用相同的参数名称。正如David所说,它很可能隐藏了外部的
T
。如果是这样的话,我也会用不同的名字。这确实是非常出乎意料的。这是令人惊讶的。虽然它确实强化了这样一种观念,即提示和警告通常应该被当作错误对待,即使在某些情况下编译器仍然会运行到完成。@J。。。我觉得这个暗示很令人惊讶。如果说这是最令人困惑的方面的话。开发人员已经充分意识到了这个问题,因此提出了一个提示,但就到此为止。他们在想什么?在意识到这是一个问题之后,他们决定让编译器保持原样,接受永远不能使用泛型参数的泛型类?这很棘手。我打算为一个双链接列表编写一个类,我发现了一个奇怪的行为,请确保编译时有提示,然后处理它们!
type
  TClassC<T1> = class
  private
    type
    TClassD<T2> = class
    private
      x: T2;
    end;
  end;