gpt4 book ai didi

delphi - 为什么这段代码在 XE3 中无法编译

转载 作者:行者123 更新时间:2023-12-03 15:52:42 26 4
gpt4 key购买 nike

type
TForm72 = class(TForm)
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

TTestForm = class(TForm)
public
constructor CreateTest(AOwner: TComponent); virtual;
end;

TTestForm1 = class(TTestForm)
public
constructor CreateTest(AOwner: TComponent); override;
end;

TTest<T: TTestForm, constructor> = class(TObject)
public
class procedure Test;
end;

var
Form72: TForm72;

implementation

{$R *.dfm}

procedure TForm72.FormCreate(Sender: TObject);
begin
TTest<TTestForm1>.Test;
end;

{ TTest<T> }

class procedure TTest<T>.Test;
var
F: T;
begin
F := T.CreateTest(Application);
Form72.Caption := F.Name;
end;

{ TTestForm }

constructor TTestForm.CreateTest(AOwner: TComponent);
begin
inherited Create(AOwner);
end;

{ TTestForm1 }

constructor TTestForm1.CreateTest(AOwner: TComponent);
begin
inherited;
Caption := 'Bang';
end;

end.

此代码在 XE2 中编译,但在 XE3 中失败,并显示“[dcc32 Error] Unit71.pas(55): E2010 不兼容类型:‘T’和‘过程、无类型指针或无类型参数’”。我做错了什么,还是编译器做错了?

最佳答案

事实上,这段代码突出显示了 XE2 中的编译器错误。在 XE2 中,代码在不应该编译的时候编译了。删除构造函数约束,编译失败并显示

E2568 Can't create new instance without CONSTRUCTOR constraint in type parameter declaration

But the constructor constraint merely states that the class has a parameterless constructor. The documentation states:

Constructor Constraints

A type parameter may be constrained by zero or one instance of the reserved word "constructor". This means that the actual argument type must be a class that defines a default constructor (a public parameterless constructor), so that methods within the generic type may construct instances of the argument type using the argument type's default constructor, without knowing anything about the argument type itself (no minimum base type requirements).

The fact that the presence or otherwise of the constructor constraint influences this code indicates that the XE2 compiler has a fault.


In XE3 the code correctly fails to compile. The only way to call a constructor with the syntax T.Create is if you are using a constructor constraint and are calling a parameterless constructor. That is not the case here and so XE3 correctly reports a compilation error.

You need some casting to make it compile.

F := T(TTestForm(T).CreateTest(Application));

这是一个well-known trick解决 Delphi 泛型实现在处理构造函数时的一些怪癖。虽然看起来很乱,但我相信这段代码是语言设计者想让我们使用的。在我看来,行为的变化是由于错误修复而导致的,XE3 的行为符合设计。

关于delphi - 为什么这段代码在 XE3 中无法编译,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12749344/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com