Delphi 7を使用して、単一の整数パラメーターを受け取るいくつかの関数があります。これらの関数は、オブジェクトに属するテキスト文字列を操作します。唯一のパラメータは、テキスト内の文字インデックスまたは単語インデックスのいずれかです。たとえば、単語iの後または文字Text [loc]の後のテキストの次の単語を取得するには、次のようにします。
function NextWord(i:Integer): String; overload;
function NextWord(loc:Integer): String; overload;
明らかに、これはあいまいです。Delphiヘルプによると、「オーバーロードされたルーチンは、使用するパラメーターの数またはパラメーターのタイプによって区別する必要があります。」そこで、2つのタイプを定義しました。
type WordIndex = Integer;
type CharIndex = Integer;
...
function NextWord(i:WordIndex): String; overload;
function NextWord(i:CharIndex): String; overload;
ただし、これらはIntegerの単なるエイリアスであるため、これは機能しません。
タイプに関するDelphiヘルプは、「タイプID」、「タイプ互換性」、および「割り当て互換性」を区別し、その区別の使用方法については何も述べていません。しかし、「type」という単語を繰り返して、Integerと同一ではない新しいタイプを作成すると言っています。
type WordIndex = type Integer; //really, a new type
type CharIndex = type Integer;
...
function NextWord(i:WordIndex): String; overload;
function NextWord(i:CharIndex): String; overload;
...
var WordNumber: WordIndex; //variable of new type
...
WordStr := NextWord(WordNumber); //call overloaded function
驚いたことに、これも機能しません。コンパイラはWordIndexを別の型として認識し、オーバーロードされた関数をコンパイルしますが、呼び出された場合、オーバーロードはあいまいであると主張します。また、関数パラメーターをVARに変更しようとしましたが(「varパラメーターの場合、形式パラメーターと実際のタイプは同一でなければならないため」)、それは役に立ちませんでした。
Webにアクセスすると、コンパイラーは、最初にパラメーターの数に基づいて、次にパラメーターのサイズに基づいて、オーバーロードされた関数を明確にすることを読みました。WordIndexを整数ではなくDWordにすることもできると思いますが、16ビットにはしたくないので、-1を使用して「無効な単語番号」を意味します。
最後に、「プロシージャと関数のオーバーロード」のヘルプでこれを見つけました。「ルーチンの宣言のいずれかとタイプが同じではないが、のパラメータと割り当て互換性のあるオーバーロードされたルーチンパラメータに渡すことができます。複数の宣言。...これらの場合、曖昧さなしにそうすることが可能であるとき、コンパイラーは、パラメーターが呼び出しの実際のパラメーターに対応する最小範囲のタイプであるルーチンを呼び出します。」
だから私はこれを試しました、それはうまくいきます:
type WordIndex = -1..High(Integer);
type CharIndex = Integer;
function NextWord(i:WordIndex): String; overload;
function NextWord(i:CharIndex): String; overload;
...
var WordNumber: WordIndex;
loc: CharIndex;
...
WordStr := NextWord(WordNumber);
(or)
WordStr := NextWord(loc);
これは警告やエラーなしでコンパイルされ、実際には各パラメータータイプに対して正しい関数を呼び出します。また、SizeOf(WordIndex)= SizeOf(CharIndex)=4です。IEは両方とも整数です。
私の質問は、これは私がそれを行うことになっている方法ですか?もしそうなら、どうやってそれを知ることになったのですか?ヘルプやソースにそのような例はありますか?
ボーナスの質問:チェックしたところ、タイプWordIndexを範囲にすると、呼び出しや関数でコード/ランタイムのオーバーヘッドが発生しません。しかし、それはコードの他の場所にあるのでしょうか?Delphiは、整数をテストしない場所で、範囲エラーについてWordNumberをテストしますか?(答えは「いいえ」だと確信しています。)