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