2011-01-29 15 views
3

文字列解析のカスタム列挙子を作成するときに、奇妙なエラーメッセージが表示されます。レコードの代わりに、私は時々、いくつかの内部エラーを取得Delphiのカスタム列挙子で奇妙なエラーが発生する

E2010 Incompatible types: 'TSplitStringEnumerator' and 'Pointer'

クラスを使用して(コード内のいくつかの.Create呼び出しを挿入):

は誰もが知っていたレコードを使用する場合は、次のエラーが発生します列挙型をクラスの代わりにレコードデータ型で保持する方法は?このコードはコンパイルとDelphi 2010年に私のために成功した出力を実行するように見える

type 
    TSplitStringEnumerator = record 
     StringToParse:   string; 
     Separator:    Char; 
     S:      Integer; 
     E:      Integer; 
     L:      Integer; 
     function GetCurrent (): string; inline; 
     function MoveNext (): Boolean; inline; 
     property Current: string read GetCurrent; 
    end; 

    TSplitStringGenerator = record 
     Enum:     TSplitStringEnumerator; 
     function GetEnumerator: TSplitStringEnumerator; inline; 
    end; 

function SplitString(const StringToParse: string; Separator: Char): TSplitStringGenerator; //inline; 
begin 
    Result.Enum.StringToParse := StringToParse; 
    Result.Enum.Separator  := Separator; 
    Result.Enum.S    := 0; 
    Result.Enum.E    := 0; 
    Result.Enum.L    := Length(StringToParse); 
end; 

procedure Test(); 
var 
    S: string; 
begin 
    for S in SplitString('A;B;C', ';') do begin 
     OutputDebugString(PChar(S)); 
    end; 
end; 

{ TSplitStringGenerator } 

function TSplitStringGenerator.GetEnumerator(): TSplitStringEnumerator; 
begin 
    Result := Enum; 
end; 

{ TSplitStringEnumerator } 

function TSplitStringEnumerator.GetCurrent(): string; 
begin 
    Result := Copy(StringToParse, S, E - S); 
end; 

function TSplitStringEnumerator.MoveNext(): Boolean; 
begin 
    S := E + 1; 
    Result := S <= L; 
    E := S; 
    while (E <= L) and (StringToParse[ E ] <> Separator) do Inc(E); 
end; 

答えて

4

私はQCに関して同様のbug report #72213を見つけました。バグはDelphi 2010で修正されました(解決コメントを参照)。

+1

+1はOPがマネージタイプを使用しているのでかなり説明しそうです –

+0

はい、文字列を置き換えますPCharはD2009のコンパイルエラーを効果的に削除します。 –

+0

D2010に移動せずに動作させるには、クラスに切り替える必要があると思います。レコードでは、管理対象のタイプを使用できない場合、リークを回避する方法はありません。 –

2

は次のとおりです。

Debug Output: A Process Project4.exe (4656) 
Debug Output: B Process Project4.exe (4656) 
Debug Output: C Process Project4.exe (4656) 

それがレコードを持つ列挙子は2007 Delphiでサポートされていないことは可能ですか?

+0

かなり可能です。コードはD2009でコンパイルされず、D2009は列挙子をサポートしています。また、forループを自分自身でコード化するとき( 'x.GetEnumerator.MoveNext'は' x.GetEnumerator.Current'で何かを行います)、実際にはコンパイルされますが、その後は無限ループに陥ります。それがRitsaertの例のコードであるのか、コンパイラがそれを混乱させているのかを判断することはできませんでした。一方、D2009のヘルプはレコードの使用がサポートされていることを明確に示しています。 –

+0

エンドレスループは、GetEnumerator関数が、呼び出すたびに新しく初期化されたEnumメンバーのバージョンを返すことによって発生します。私は 'Result:= RecordMember'がRecordMemberのもののコピーをResultにコピーすると思いましたか?そして、私が 'x.GetEnumerator.Whatever'を' x.Enum.Whatever'に変更すると、... –

関連する問題