私は、コンパイル段階で特定の種類のバグをキャッチするために、強く型付けされたtypedefを宣言する方法を考えていました。多くの場合、intをいくつかのタイプのIDにtypedefするか、位置または速度を指定するベクトルを入力します。
typedef int EntityID;
typedef int ModelID;
typedef Vector3 Position;
typedef Vector3 Velocity;
これにより、コードの意図をより明確にすることができますが、長い夜のコーディングの後、さまざまな種類のIDを比較したり、速度に位置を追加したりするなど、愚かな間違いを犯す可能性があります。
EntityID eID;
ModelID mID;
if ( eID == mID ) // <- Compiler sees nothing wrong
{ /*bug*/ }
Position p;
Velocity v;
Position newP = p + v; // bug, meant p + v*s but compiler sees nothing wrong
残念ながら、厳密に型指定されたtypedefについて私が見つけた提案には、少なくとも私にとっては不可能なブーストの使用が含まれています(少なくともc ++ 11があります)。少し考えてから、私はこのアイデアに思いつき、誰かがそれを実行したいと考えました。
最初に、ベースタイプをテンプレートとして宣言します。ただし、テンプレートパラメータは定義内の何にも使用されていません。
template < typename T >
class IDType
{
unsigned int m_id;
public:
IDType( unsigned int const& i_id ): m_id {i_id} {};
friend bool operator==<T>( IDType<T> const& i_lhs, IDType<T> const& i_rhs );
};
フレンド関数は、クラス定義の前に実際に前方宣言する必要があります。これには、テンプレートクラスの前方宣言が必要です。
次に、基本型のすべてのメンバーを定義しますが、それはテンプレートクラスであることを覚えているだけです。
最後に、使用したい場合は、次のようにtypedefします。
class EntityT;
typedef IDType<EntityT> EntityID;
class ModelT;
typedef IDType<ModelT> ModelID;
タイプは完全に分離されました。たとえば、EntityIDを受け取る関数は、ModelIDを代わりにフィードしようとすると、コンパイラエラーをスローします。基本型をテンプレートとして宣言する必要があることを除いて、それに伴う問題とともに、かなりコンパクトです。
私は誰かがこのアイデアについてコメントや批評を持っていることを望んでいましたか?
これを書いているときに頭に浮かんだ問題の1つは、たとえば位置や速度の場合、以前ほど自由に型を変換できないことです。ベクトルをスカラーで乗算する前に別のベクトルが得られるので、次のことができます:
typedef float Time;
typedef Vector3 Position;
typedef Vector3 Velocity;
Time t = 1.0f;
Position p = { 0.0f };
Velocity v = { 1.0f, 0.0f, 0.0f };
Position newP = p + v*t;
強く型付けされたtypedefを使用して、VelocityをTimeでマルチタイピングするとPositionになることをコンパイラーに伝える必要があります。
class TimeT;
typedef Float<TimeT> Time;
class PositionT;
typedef Vector3<PositionT> Position;
class VelocityT;
typedef Vector3<VelocityT> Velocity;
Time t = 1.0f;
Position p = { 0.0f };
Velocity v = { 1.0f, 0.0f, 0.0f };
Position newP = p + v*t; // Compiler error
これを解決するには、すべての変換を明示的に特化する必要があると思いますが、これは面倒です。一方、この制限は、他の種類のエラー(たとえば、このドメインでは意味をなさない、速度に距離を乗算するなど)を防ぐのに役立ちます。だから私は破れ、私の元の問題、またはそれを解決するための私のアプローチについて人々が何か意見を持っているのではないかと思っています。