現在同じ型の引数を取るいくつかの関数について、コンパイル時に本質的に「型」情報が何であるかを追跡したいと思います。以下に例を示します。と の 2 つの関数があるgetThingIndex(uint64_t t)
としgetThingAtIndex(uint64_t tidx)
ます。最初の関数は、引数を のエンコーディングとして扱い、thing
インデックスの重要な計算を行い、それを返します。を呼び出すことで、実際の「もの」を取得できgetThingAtIndex
ます。getThingAtIndex
一方、構造を照会していて、既にインデックスがあると想定しています。2 つの方法のうち後者の方が高速ですが、より重要なことは、 to を渡すこと、またはthing
toを渡すことによって生じる頭痛を避けたいということです。getThingAtIndex
index
getThingIndex
thing
私は次のような種類のインデックスを作成することを考えていました:
struct Thing { uint64_t thing; }
struct ThingIndex { uint64_t idx; }
そして、上記の関数のシグネチャを次のように変更します
getThingIndex(Thing t)
getThingAtIndex(ThingIndex idx)
現在、と が同じ基になる型Thing
をエンコードしているにもかかわらず、それらはコンパイル時に区別されるため、 にインデックスまたはものをThingIndex
渡すことで愚かな間違いを犯す機会が少なくなり
ます。getThingIndex
getThingAtIndex
ただし、このアプローチのオーバーヘッドが心配です。関数は何回も (数千万回から数億回) 呼び出されますが、基本的にコンパイル時の型情報をエンコードするだけのこれらの構造の作成をコンパイラが最適化して排除するかどうかに興味があります。コンパイラがそのような最適化を実行しない場合、これらのタイプの「豊富なタイプ」をオーバーヘッドなしで作成する方法はありますか?