Delphi通用嵌套类

时间:2017-11-07 20:39:46

标签: delphi generics

我正在对C ++和Delphi进行比较,我发现了一些棘手的问题。

这是非常简单的C ++代码:

C

在这种情况下,我们认为类D是模板类(=泛型类),嵌套类T也是模板类。如果doublex,则D内的doubletemplate<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

如果integerx,那么现在integerTClassD,因为(据我所知,在线阅读)integer是{{} 1}}。在德尔福,这也是合法的:

type
 TClassC<T> = class
  private

   type
    TClassD<T> = class // <-- note the <T> repeated!!
     private 
      x: T;
    end;

 end;

现在呢?如果我能够在T中再次声明TClassD,这意味着如果没有<T>,我会有一个非通用的TClassD类。我是对的吗?

1 个答案:

答案 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语言的设计缺点是你可以在这个答案的顶部编译代码。