Delphi通用嵌套类

Raf*_*ssi 14 delphi generics

我正在对C++和Delphi进行比较,我发现了一些棘手的东西.

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

template<typename T>
class C {

 class D {
  T x;
 }

}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我们认为类C是模板类(=泛型类),嵌套类D也是模板类.如果Tdouble,则x内部Ddouble.

我不能这样说:

template<typename T>
class C {

 template<typename T>
 class D {
  T x;
 }

}
Run Code Online (Sandbox Code Playgroud)

这是一个错误,因为我已经"内部" C而另一个T将是一个冲突.要修复错误,我应该使用不同的名称,例如U.

template<typename T>
class C {

 template<typename U>
 class D {
  T x;
 }

}
Run Code Online (Sandbox Code Playgroud)

在Delphi中,我可以这样写:

type
 TClassC<T> = class
  private

   type
    TClassD = class
     private 
      x: T;
    end;

 end;
Run Code Online (Sandbox Code Playgroud)

如果T是一个integer,现在x是一个integer(从我所理解的在线阅读)TClassDinteger.在Delphi中,这也是合法的:

type
 TClassC<T> = class
  private

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

 end;
Run Code Online (Sandbox Code Playgroud)

现在呢?如果我能够T再次声明TClassD,这意味着没有<T>我有一个非泛型TClassD类.我对么?

Dav*_*nan 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.
Run Code Online (Sandbox Code Playgroud)

该程序编译,但会发出以下提示:

[dcc32提示]:H2509标识符'T'与容器类型的类型参数冲突

赋值证明x从外部泛型参数而不是内部参数获取其类型.

我不得不说这令我感到惊讶,因为我期待相反的事情.我原以为内部泛型参数会隐藏外部参数.事实上,据我所知,内部类型无法引用其泛型参数.

为了能够引用这两个通用参数,您需要为它们使用不同的名称.例如:

type
  TClassC<T1> = class
  private
    type
    TClassD<T2> = class
    private
      x: T2;
    end;
  end;
Run Code Online (Sandbox Code Playgroud)

这就是类似的C++模板代码强制您做的事情.

在我看来,Delphi语言的设计缺点是允许您在本答案的顶部编译代码.

  • @J ......我觉得这个提示非常令人惊讶.如果有什么是这个最令人困惑的方面.开发人员已经充分意识到这个问题是为了提出一个暗示,但随后就这样了.他们在想什么?已经意识到这是一个问题,他们决定保留编译器,接受泛型类,其中泛型参数永远不会被使用? (3认同)