次のようなテンプレート関数があります。
template <class T> void foo(T* t)
{
//do stuff using:
someArray[idx]; //idx depends on T
}
考えられる型はいくつかあるT
ので、私のアプローチは名前のない名前空間で次のようなことをすることでした:
struct Sentinel;
template <class T> struct Offsets {};
#define GENIDX(T,NUM) template <> struct Offsets<T> {static const int idx = NUM;};
GENIDX(Fox, 0)
GENIDX(Cat, 1)
GENIDX(Rat, 2)
GENIDX(Sentinel, 3)
static const size_t numTypes = Offsets<Sentinel>::idx;
その後、メンバー配列someArray
は次のように宣言されますsomeArray[numTypes];
foo メソッドは次のように実装されます。
template <class T> void foo(T* t)
{
typedef Offsets<T> offset_t;
someArray[offset_t::idx]; //idx depends on T
}
誰かがシステムに新しいタイプを追加する必要がある場合は、新しいタイプを追加するだけGENIDX
ですべてが機能します。唯一の煩わしさは、誰かがたとえばミックスに追加したいが、残りのインデックスを手動でバンプWolf
する前に論理的に表示したい場合です。Cat
マクロで数値インデックスを必要とせず、代わりにそれらを自動的に順次生成させる方法があるかどうか疑問に思っていました。以下が機能しないことを除いて、このようなもの:
size_t numTypes = 0;
template <class T> struct Offsets {};
#define GENIDX(T) template <> struct Offsets<T> {static const int idx = numTypes++;};
GENIDX(Fox)
GENIDX(Cat)
GENIDX(Rat)
その後numTypes
、配列のサイズが正しく含まれます。これにより、ミックス内のどこかに新しい特殊化を挿入するときにインデックス管理が不要になります。少なくとも好奇心の観点からは、これがどのように行われるかを知ることは興味深いでしょう。
__COUNTER__
また、これを行っても、gccバージョンがないことに気付いた後:
template <class T> struct Offsets {};
#define GENIDX(T) \
template <> struct Offsets<T> \
{ \
#include BOOST_PP_UPDATE_COUNTER() \
static const int idx = COUNTER; \
};
#include
しかし、マクロ内で言うことができないため、上記は失敗します...