почему отсутствующий необязательный параметр вызывает ошибку несовместимых типов

Может кто-нибудь объяснить, почему я получаю сообщение об ошибке «Несовместимый тип» (Delphi XE3) в следующей программе (подробности см. в комментариях внизу кода), когда я опускаю необязательный параметр для конструктора?

program Test;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,
  System.Classes;

type
  BaseClass = class(TObject);

  ChildClass = class(BaseClass);

  GenericBaseClass<T> = class
  public
    constructor Create(Fixed: Integer);
  end;

  GenericClass<T: BaseClass> = class(GenericBaseClass<T>)
  public
    type
      TMyProc = procedure (DataObject: T) of object;
  public
    constructor Create(Fixed: String; Optional: TMyProc = nil);
  end;

constructor GenericClass<T>.Create(Fixed: String; Optional: TMyProc);
begin
  inherited Create(12);
end;

constructor GenericBaseClass<T>.Create(Fixed: Integer);
begin
  inherited Create();
end;

var
  Gc: GenericClass<ChildClass>;

begin
  // this call is okay
  Gc := GenericClass<ChildClass>.Create('', nil);
  // this call fails: E2010 Incompatible types: 'ChildClass' and 'T'
  Gc := GenericClass<ChildClass>.Create('');
end.

person TmTron    schedule 28.05.2013    source источник
comment
Сообщение об ошибке подсказывает мне, что создание экземпляров универсальных типов не работает для аргументов по умолчанию, что аргумент по умолчанию GenericClass<ChildClass> остается константой nil типа GenericClass<T>.TMyProc, а не предполагаемой константой nil типа GenericClass<ChildClass>.TMyProc. Можете ли вы проверить это, проверив, работают ли аргументы по умолчанию независимых типов?   -  person    schedule 28.05.2013
comment
независимые типы, похоже, работают (например, когда я меняю тип параметра Optional с TMyProc на Pointer, он работает), ваше объяснение звучит разумно, спасибо.   -  person TmTron    schedule 29.05.2013


Ответы (1)


Добавьте reintroduce или overload к конструктору GenericClass, поскольку у вас есть несколько конструкторов с одинаковым именем, но разными параметрами.

person Remy Lebeau    schedule 28.05.2013
comment
То, как я читаю вопрос, скрывает конструктор базового класса намеренно, поэтому overload будет неправильным. И reintroduce не должен иметь никакого эффекта, кроме подавления предупреждения для объявления класса, не так ли? - person ; 28.05.2013