Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Generics vs. модули - конфликт областей видимости


Автор: Skiminok 3.11.2008, 20:22
Приветствую весь честной люд. У меня вопрос по Delphi 2009. Надеюсь, на форуме найдутся люди, которые уже экспериментировали с дженериками и смогут ответить на один маленький вопрос по очень странной ошибке...

Я решил попробовать воспользоваться новой, обобщённой версией библиотеки DeCAL (Delphi Container and Algorithm Library) - http://cc.codegear.com/Item/26124. Но тут код, использовавший DMap из старой версии DeCAL, даже после пары очевидных переделок, напрочь отказался компилироваться. Тогда я решил выделить это использование в маленькую, упрощённую программу, и добился появления той же ошибки. Ошибки странной и дурацкой, я не могу её понять.

Вот простая и маленькая программа:
Код
program Project1;

{$APPTYPE CONSOLE}

uses
  DeCAL.Algo in 'DeCAL.Algo.pas',
  DeCAL.Containers in 'DeCAL.Containers.pas',
  DeCAL.Identity in 'DeCAL.Identity.pas',
  mwFixedRecSort in 'mwFixedRecSort.pas',
  Unit1 in 'Unit1.pas';

var
  It: DIterator<TSmth>;

begin
  a := DMap<String, TSmth>.Create;
  a.add('1', smOne);
  a.add('2', smTwo);
  a.add('3', smThree);
  It := a.locate('2');
  Writeln(Integer(It.get));
  a.Free;
end.


Она, как видите, используется нижеприведённый модуль:
Код
unit Unit1;

interface

uses
  DeCAL.Containers;

type
  TSmth = (smOne, smTwo, smThree);

var
  a: DMap<String, TSmth>;

implementation

end.


Компилятор выдаёт следующее:
E2010 Incompatible types: 'DIterator<Unit1.TSmth>' and 'DIterator<TSmth>.'
Что значит несовместимы? Это один и тот же generic, инстациированный одним и тем же типом! Единственное различие - что переменная "а" находится в отдельном модуле. Кстати, если перенести её непосредственно в текст основной программы, ошибка исчезает... но меня такое решение по разным причинам не устраивает.
Пытался добавить в разные места кода уточнение "Unit1." - безрезультатно.

Кто что может сказать по поводу?

З.Ы.
Вот объявление метода DMap.locate в DeCAL.Containers.pas:
Код
type
  DMap<TKey,TValue> = class
  // ...
    function locate(const key: TKey): DIterator<TValue>;
  // ...
end;

Автор: Skiminok 3.11.2008, 20:47
Вопрос снят Крэйгом Станцем на forums.codegear.com.
Оказывается, дженерики для глобальных переменных попросту не поддерживаются. После следующего маленького видоизменения ошибка исчезла бесследно:

Unit1.pas:
Код
type
  TSmth = (smOne, smTwo, smThree);
  TGlobals = class
    class var
      a: DMap<String, TSmth>;
  end;


Project1.dpr:
Код
With TGlobals do begin
    a := DMap<String, TSmth>.Create;
    a.add('1', smOne);
    a.add('2', smTwo);
    a.add('3', smThree);
    It := a.locate('2');
    Writeln(Integer(It.get));
    a.Free;
  end;

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)